diff --git a/.eslintignore b/.eslintignore index 25dff64df3..22a60fa754 100644 --- a/.eslintignore +++ b/.eslintignore @@ -14,6 +14,7 @@ libtextsecure/components.js libtextsecure/test/test.js test/test.js ts/protobuf/compiled.d.ts +storybook-static/** # Third-party files js/Mp3LameEncoder.min.js diff --git a/.eslintrc.js b/.eslintrc.js index b9d4c7e78e..47c8f72b55 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,16 @@ const rules = { 'brace-style': ['error', '1tbs', { allowSingleLine: false }], curly: ['error', 'all'], + // Immer support + 'no-param-reassign': [ + 'error', + { + props: true, + ignorePropertyModificationsForRegex: ['^draft'], + ignorePropertyModificationsFor: ['acc', 'ctx', 'context'], + }, + ], + // Always use === and !== except when directly comparing to null // (which only will equal null or undefined) eqeqeq: ['error', 'always', { null: 'never' }], @@ -290,6 +300,12 @@ module.exports = { 'local-rules/type-alias-readonlydeep': 'error', }, }, + { + files: ['ts/**/*_test.{ts,tsx}'], + rules: { + 'func-names': 'off', + }, + }, ], rules: { diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 05e4140738..04ac27558a 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -12,7 +12,7 @@ on: jobs: linux: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8-cores if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' }} timeout-minutes: 30 @@ -28,7 +28,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' - name: Install global dependencies run: npm install -g yarn@1.22.10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b15eb26ee9..bea4bf3f69 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ on: jobs: lint: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8-cores timeout-minutes: 30 steps: @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' - run: npm install -g yarn@1.22.10 - name: Cache Desktop node_modules @@ -72,7 +72,12 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' + + # The version of node-gyp bundled with our node/npm version does not support python 3.12, which the runner uses + # When we update node again, we can probably remove this + - run: npm install -g npm@latest + - run: npm install -g yarn@1.22.10 - name: Cache Desktop node_modules @@ -121,7 +126,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' - run: sudo apt-get install xvfb - run: npm install -g yarn@1.22.10 @@ -144,7 +149,7 @@ jobs: run: yarn build:esbuild:prod - name: Build with packaging .deb file - run: yarn build:release + run: yarn build:release -- --publish=never if: github.ref == 'refs/heads/main' env: DISABLE_INSPECT_FUSE: on @@ -187,9 +192,9 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' - run: npm install -g yarn@1.22.10 - + # Set things up so @nodert-win10-rs4 dependencies build properly - run: dir "$env:BUILD_LOCATION" - run: dir "$env:SDK_LOCATION" @@ -206,7 +211,7 @@ jobs: if: steps.cache-desktop-modules.outputs.cache-hit != 'true' run: yarn install --frozen-lockfile env: - CHILD_CONCURRENCY: 1 + CHILD_CONCURRENCY: 1 NPM_CONFIG_LOGLEVEL: verbose - run: yarn generate @@ -246,7 +251,7 @@ jobs: mock-tests: needs: lint - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8-cores if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' }} timeout-minutes: 30 @@ -262,7 +267,7 @@ jobs: - name: Setup node.js uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' - name: Install global dependencies run: npm install -g yarn@1.22.10 diff --git a/.github/workflows/commits.yml b/.github/workflows/commits.yml new file mode 100644 index 0000000000..fc7684284c --- /dev/null +++ b/.github/workflows/commits.yml @@ -0,0 +1,19 @@ +# Copyright 2023 Signal Messenger, LLC +# SPDX-License-Identifier: AGPL-3.0-only + +name: Commits Check +on: + push: + branches: + - main + - '[0-9]+.[0-9]+.x' +jobs: + linux: + runs-on: ubuntu-latest + if: ${{ github.repository == 'signalapp/Signal-Desktop-Private' }} + steps: + - uses: signalapp/Signal-Check-Commits-Action-Private@main + with: + commit-pattern: "\\(#\\d{1,}\\)" # i.e. "Example commit message (#1234)" + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-title: Pushed to "${{ github.ref_name }}" with issue references diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 8d827514c2..2750f564c3 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -1,7 +1,7 @@ # Copyright 2020 Signal Messenger, LLC # SPDX-License-Identifier: AGPL-3.0-only -name: CI +name: Danger on: pull_request: @@ -15,7 +15,7 @@ jobs: fetch-depth: 0 # fetch all history - uses: actions/setup-node@v3 with: - node-version: '18.15.0' + node-version: '18.17.1' - run: npm install -g yarn@1.22.10 - name: Cache danger node_modules id: cache-desktop-modules diff --git a/.github/workflows/stories.yml b/.github/workflows/stories.yml new file mode 100644 index 0000000000..b96b476c98 --- /dev/null +++ b/.github/workflows/stories.yml @@ -0,0 +1,23 @@ +# Copyright 2023 Signal Messenger, LLC +# SPDX-License-Identifier: AGPL-3.0-only +name: Stories +on: + push: + branches: + - development + - main + - '[0-9]+.[0-9]+.x' + pull_request: +jobs: + test: + runs-on: ubuntu-latest-8-cores + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '18.17.1' + cache: 'yarn' + - run: yarn install --frozen-lockfile + - run: yarn build:storybook + - run: yarn run-p --race test:storybook:serve test:storybook:test diff --git a/.nvmrc b/.nvmrc index 55bffd620b..4a1f488b6c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.15.0 +18.17.1 diff --git a/.prettierignore b/.prettierignore index d8437df316..9283a8ab81 100644 --- a/.prettierignore +++ b/.prettierignore @@ -18,6 +18,8 @@ ts/protobuf/*.d.ts ts/protobuf/*.js stylesheets/manifest.css ts/util/lint/exceptions.json +storybook-static +build/locale-display-names.json # Third-party files node_modules/** @@ -30,6 +32,9 @@ js/WebAudioRecorderMp3.js /images/ /fixtures/ +# Version control +**/.git + # Github workflows .github/** diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index 3310856f67..0000000000 --- a/.storybook/main.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2022 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -module.exports = { - typescript: { - reactDocgen: false, - }, - stories: ['../ts/components/**/*.stories.tsx'], - addons: [ - '@storybook/addon-a11y', - '@storybook/addon-actions', - '@storybook/addon-controls', - '@storybook/addon-measure', - '@storybook/addon-toolbars', - '@storybook/addon-viewport', - - // This must be imported last. - '@storybook/addon-interactions', - - // Deprecated! Please remove when all uses have been migrated to controls. - '@storybook/addon-knobs', - ], - core: { - builder: 'webpack5', - }, - features: { - storyStoreV7: true, - }, -}; diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000000..5a49c7f237 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,102 @@ +// Copyright 2022 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { StorybookConfig } from '@storybook/react-webpack5'; +import { ProvidePlugin } from 'webpack'; + +const config: StorybookConfig = { + typescript: { + reactDocgen: false, + }, + stories: ['../ts/components/**/*.stories.tsx'], + addons: [ + '@storybook/addon-a11y', + '@storybook/addon-actions', + '@storybook/addon-controls', + '@storybook/addon-measure', + '@storybook/addon-toolbars', + '@storybook/addon-viewport', + '@storybook/addon-jest', + + // This must be imported last. + '@storybook/addon-interactions', + ], + framework: '@storybook/react-webpack5', + core: {}, + features: { + storyStoreV7: true, + }, + staticDirs: [ + { from: '../fonts', to: 'fonts' }, + { from: '../images', to: 'images' }, + { from: '../fixtures', to: 'fixtures' }, + { + from: '../node_modules/emoji-datasource-apple/img', + to: 'node_modules/emoji-datasource-apple/img', + }, + ], + webpackFinal(config) { + config.cache = { + type: 'filesystem', + }; + + config.resolve!.extensions = ['.tsx', '.ts', '...']; + + config.module!.rules!.unshift({ + test: /\.scss$/, + use: [ + { loader: 'style-loader' }, + { loader: 'css-loader', options: { modules: false, url: false } }, + { loader: 'sass-loader' }, + ], + }); + + config.module!.rules!.unshift({ + test: /\.css$/, + use: [ + // prevent storybook defaults from being applied + ], + }); + + config.node = { global: true }; + + config.externals = { + net: 'commonjs net', + vm: 'commonjs vm', + fs: 'commonjs fs', + async_hooks: 'commonjs async_hooks', + module: 'commonjs module', + stream: 'commonjs stream', + tls: 'commonjs tls', + dns: 'commonjs dns', + http: 'commonjs http', + https: 'commonjs https', + os: 'commonjs os', + constants: 'commonjs constants', + zlib: 'commonjs zlib', + '@signalapp/libsignal-client': 'commonjs @signalapp/libsignal-client', + '@signalapp/libsignal-client/zkgroup': + 'commonjs @signalapp/libsignal-client/zkgroup', + '@signalapp/ringrtc': 'commonjs @signalapp/ringrtc', + '@signalapp/better-sqlite3': 'commonjs @signalapp/better-sqlite3', + electron: 'commonjs electron', + 'fs-xattr': 'commonjs fs-xattr', + fsevents: 'commonjs fsevents', + 'mac-screen-capture-permissions': + 'commonjs mac-screen-capture-permissions', + sass: 'commonjs sass', + bufferutil: 'commonjs bufferutil', + 'utf-8-validate': 'commonjs utf-8-validate', + }; + + config.plugins!.push( + new ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + }) + ); + + return config; + }, +}; + +export default config; diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index ce8fe08d0b..0000000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index ae3ec18f16..2cd8d32b27 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,17 +1,29 @@ // Copyright 2019 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only +import '../ts/window.d.ts'; + import React from 'react'; -import classnames from 'classnames'; -import { withKnobs, boolean, optionsKnob } from '@storybook/addon-knobs'; + +import 'sanitize.css'; +import '../stylesheets/manifest.scss'; +import '../node_modules/@indutny/frameless-titlebar/dist/styles.css'; import * as styles from './styles.scss'; import messages from '../_locales/en/messages.json'; -import { ClassyProvider } from '../ts/components/PopperRootContext'; import { StorybookThemeContext } from './StorybookThemeContext'; import { ThemeType } from '../ts/types/Util'; import { setupI18n } from '../ts/util/setupI18n'; import { HourCyclePreference } from '../ts/types/I18N'; +import { Provider } from 'react-redux'; +import { Store, combineReducers, createStore } from 'redux'; +import { StateType } from '../ts/state/reducer'; +import { + ScrollerLockContext, + createScrollerLock, +} from '../ts/hooks/useScrollLock'; + +const i18n = setupI18n('en', messages); export const globalTypes = { mode: { @@ -38,8 +50,75 @@ export const globalTypes = { }, }; -window.i18n = setupI18n('en', messages); -window.getHourCyclePreference = () => HourCyclePreference.UnknownPreference; +const mockStore: Store = createStore( + combineReducers({ + calling: (state = {}) => state, + conversations: ( + state = { + conversationLookup: {}, + targetedConversationPanels: {}, + } + ) => state, + globalModals: (state = {}) => state, + user: (state = {}) => state, + }) +); + +// eslint-disable-next-line +const noop = () => {}; + +window.Whisper = window.Whisper || {}; +window.Whisper.events = { + on: noop, +}; + +window.SignalContext = { + i18n, + + activeWindowService: { + isActive: () => true, + registerForActive: noop, + unregisterForActive: noop, + registerForChange: noop, + unregisterForChange: noop, + }, + + nativeThemeListener: { + getSystemTheme: () => 'light', + subscribe: noop, + unsubscribe: noop, + update: () => 'light', + }, + Settings: { + themeSetting: { + getValue: async () => 'light', + setValue: async () => 'light', + }, + waitForChange: () => new Promise(noop), + }, + OS: { + hasCustomTitleBar: () => false, + getClassName: () => '', + platform: '', + release: '', + }, + usernames: { + hash: input => Buffer.from(input), + } as any, + config: {} as any, + + getHourCyclePreference: () => HourCyclePreference.UnknownPreference, + getPreferredSystemLocales: () => ['en'], + getResolvedMessagesLocaleDirection: () => 'ltr', + getLocaleOverride: () => null, + getLocaleDisplayNames: () => ({ en: { en: 'English' } }), +}; + +window.i18n = i18n; +window.ConversationController = window.ConversationController || {}; +window.ConversationController.isSignalConversationId = () => false; +window.ConversationController.onConvoMessageMount = noop; +window.reduxStore = mockStore; const withModeAndThemeProvider = (Story, context) => { const theme = @@ -75,7 +154,29 @@ const withModeAndThemeProvider = (Story, context) => { ); }; -export const decorators = [withModeAndThemeProvider]; +function withMockStoreProvider(Story, context) { + return ( + + + + ); +} + +function withScrollLockProvider(Story, context) { + return ( + {})} + > + + + ); +} + +export const decorators = [ + withModeAndThemeProvider, + withMockStoreProvider, + withScrollLockProvider, +]; export const parameters = { axe: { diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index c11fdbe046..0000000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2019 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -const webpack = require('webpack'); - -module.exports = ({ config }) => { - config.entry.unshift('!!style-loader!css-loader!sanitize.css'); - - config.cache = { - type: 'filesystem', - }; - - config.module.rules.unshift({ - test: /\.scss$/, - use: [ - { loader: 'style-loader' }, - { loader: 'css-loader?modules=true&localsConvention=camelCaseOnly' }, - { loader: 'sass-loader' }, - ], - }); - - config.node = { global: true }; - - config.externals = { - net: 'commonjs net', - vm: 'commonjs vm', - fs: 'commonjs fs', - async_hooks: 'commonjs async_hooks', - module: 'commonjs module', - stream: 'commonjs stream', - tls: 'commonjs tls', - dns: 'commonjs dns', - http: 'commonjs http', - https: 'commonjs https', - os: 'commonjs os', - constants: 'commonjs constants', - zlib: 'commonjs zlib', - '@signalapp/libsignal-client': 'commonjs @signalapp/libsignal-client', - '@signalapp/libsignal-client/zkgroup': - 'commonjs @signalapp/libsignal-client/zkgroup', - '@signalapp/ringrtc': 'commonjs @signalapp/ringrtc', - '@signalapp/better-sqlite3': 'commonjs @signalapp/better-sqlite3', - electron: 'commonjs electron', - 'fs-xattr': 'commonjs fs-xattr', - fsevents: 'commonjs fsevents', - 'mac-screen-capture-permissions': 'commonjs mac-screen-capture-permissions', - sass: 'commonjs sass', - bufferutil: 'commonjs bufferutil', - 'utf-8-validate': 'commonjs utf-8-validate', - }; - - return config; -}; diff --git a/.yarnclean b/.yarnclean index 4593ef707b..230d0afc65 100644 --- a/.yarnclean +++ b/.yarnclean @@ -41,3 +41,6 @@ Gruntfile.js # asset directories !nyc/node_modules/istanbul-reports/lib/html/assets + +# bad matches +!patch-package/node_modules/yaml/dist/doc diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index 6e91dd01b6..87312f7a20 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -457,6 +457,210 @@ Signal Desktop makes use of the following open source projects. License: MIT +## @react-aria/utils + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ## @react-spring/web MIT License @@ -1697,30 +1901,6 @@ Signal Desktop makes use of the following open source projects. License: ISC -## history - - MIT License - - Copyright (c) React Training 2016-2018 - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - ## humanize-duration This is free and unencumbered software released into the public domain. @@ -2494,6 +2674,414 @@ Signal Desktop makes use of the following open source projects. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +## react-aria + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +## react-aria-components + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ## react-blurhash License: MIT @@ -2863,6 +3451,28 @@ Signal Desktop makes use of the following open source projects. License: (MIT OR CC0-1.0) +## urlpattern-polyfill + + Copyright 2020 Intel Corporation + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ## uuid License: MIT diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c93c214ce3..ef159888ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,10 +34,10 @@ Install the [Xcode Command-Line Tools](http://osxdaily.com/2014/02/12/install-co ### Windows -1. Download _Build Tools for Visual Studio 2017_ from the [Visual Studio 'older downloads' page](https://visualstudio.microsoft.com/vs/older-downloads/) and install it, including the "Desktop development with C++" option. +1. Download _Build Tools for Visual Studio 2019_ from the [Visual Studio 'older downloads' page](https://visualstudio.microsoft.com/vs/older-downloads/) and install it, including the "Desktop development with C++" option. 2. Install Windows 10 SDK, version 1803 (10.0.17134.x) from the [SDK Archive page](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive) 3. Download and install the latest Python 3 release from https://www.python.org/downloads/windows/ (3.6 or later required). -4. Copy `platform.winmd` from your build tools location (like `C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\lib\x86\store\references`) to the Windows SDK path: `C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17134.0`. This is for our [`@nodert-win10-rs4`](https://github.com/NodeRT/NodeRT) dependencies. +4. Copy `platform.winmd` from your build tools location (like `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\lib\x86\store\references`) to the Windows SDK path: `C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17134.0`. This is for our [`@nodert-win10-rs4`](https://github.com/NodeRT/NodeRT) dependencies. ### Linux diff --git a/_locales/af-ZA/messages.json b/_locales/af-ZA/messages.json index 07aa488ba4..691be401b6 100644 --- a/_locales/af-ZA/messages.json +++ b/_locales/af-ZA/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Databasisfout", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "'n Databasisfout het voorgekom. Jy kan die fout kopieer en Signal-steundiens kontak om die probleem te help oplos. As jy Signal dadelik moet gebruik, kan jy jou data skrap en weer begin.\n\nKontak die steundiens deur te gaan na: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Skrap alle data en begin weer", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Skrap data en begin weer", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Skrap alle data permanent?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Jou hele boodskapgeskiedenis en media sal permanent van hierdie toestel geskrap word. Jy sal Signal op hierdie toestel kan gebruik nadat jy dit herkoppel het. Dit sal nie enige data van jou foon af skrap nie.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Die weergawe van jou databasis pas nie by hierdie weergawe van Signal nie. Maak seker dat jy die jongste weergawe van Signal op jou rekenaar oopmaak.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&LĂȘer", @@ -300,6 +316,70 @@ "messageformat": "Kletse", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Iets het verkeerd geloop met jou gebruikernaam, dit is nie meer aan jou rekening toegewys nie. Jy kan probeer om dit weer op te stel of 'n nuwe een kies.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Stel nou reg", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Iets het verkeerd geloop met jou QR-kode en gebruikernaamskakel, dit is nie meer geldig nie. Skep 'n nuwe skakel om met ander te deel.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Stel nou reg", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Wys navigasie-ikone", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Versteek navigasie-ikone", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "'n Fout het voorgekom", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ongelees", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "As ongelees gemerk", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Kletse", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Oproepe", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Instellings", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Dateer Signal op", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profiel", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Terug", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Hierdie kletse is geargiveer en sal slegs in die Inkassie verskyn indien nuwe boodskappe ontvang word.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Skakel in elk geval", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Sluit in elk geval aan", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Sit oproep voort", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Veiligheidsnommers word tans op datum gebring.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Vind meer uit", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Vorige Veiligheidsnommer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Volgende Veiligheidsnommer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Veiligheidsnommerweergawe, {index,number} van {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Merk as geverifieer", @@ -663,33 +747,41 @@ "messageformat": "Maak verifiĂ«ring skoon", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Om end-tot-end-enkriptering met {name} te verifieer, vergelyk die nommers hierbo met hul toestel. Hulle kan ook jou kode met hul toestel skandeer.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Vind meer uit", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Om jou end-tot-end-enkriptering met {name} te verifieer, vergelyk die kleurkaart hierbo met hul toestel en vergelyk die nommers. As diĂ© nie ooreenstem nie, probeer die ander paar veiligheidsnommers. Slegs een paar hoef ooreen te stem.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Om end-tot-end-enkriptering met {name} te verifieer, vergelyk die nommers hierbo met hul toestel. Hulle kan ook jou kode met hul toestel skandeer.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Veranderinge aan veiligheidsnommers", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Veiligheidsnommers word gedurende 'n oorgangstydperk op datum gebring om komende privaatheidskenmerke in Signal te aktiveer.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Om veiligheidsnommers te verifieer, vergelyk die kleurkaart met jou kontak se toestel. As diĂ© nie ooreenstem nie, probeer die ander paar veiligheidsnommers. Slegs een paar hoef ooreen te stem.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Hulp nodig?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Ek verstaan", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "'n Veiligheidsnommer sal met hierdie persoon geskep word nadat jy boodskappe met hulle uitgeruil het.", @@ -1267,10 +1359,6 @@ "messageformat": "Kyk na onlangse media", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Om die sekuriteit van jou end-tot-end-enkriptering met {name} te verifieer, vergelyk die nommers hierbo met hulle toestel. Hulle kan ook die qr-kode hierbo skandeer.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Jy het nog geen boodskappe met hierdie kontak verruil nie. Jou veiligheidsnommer met hulle sal na die eerste boodskap beskikbaar wees." }, @@ -1334,17 +1422,17 @@ "messageformat": "Inligting", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Skrap", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Skrap boodskappe", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Skrap klets?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Skrap boodskap?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Hierdie klets sal van hierdie toestel af geskrap word.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Boodskappe in hierdie klets sal van hierdie toestel af geskrap word. Jy kan steeds vir hierdie klets soek nadat jy boodskappe uitgevee het.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Verlaat groep", @@ -1438,6 +1526,14 @@ "messageformat": "Jou boodskap vir beide kletse is hier saamgevoeg.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} behoort aan {conversationTitle}. Julle is albei lede van {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} behoort aan {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Duimnael van die beeld uit die aangehaalde boodskap", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Bel weer", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Begin oproep", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Sluit aan by oproep", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofoon gedemp a.g.v. die grootte van die oproep", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Oproepkennisgewings", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Oproep is vol", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Sluit aan", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Begin", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Oproep vol", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera gedeaktiveer", @@ -1621,10 +1725,6 @@ "messageformat": "Skakel kamera aan", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Demp", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofoon gedeaktiveer", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ontdemp mikrofoon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Deel", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Aanbieding gedeaktiveer", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Stop aanbieding", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Bel", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Groep is te groot om deelnemers te bel.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Aktiveer lui", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Skakel lui af", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Skakel lui aan", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Meer opsies", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Jy", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Jou kamera is af", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Bekyk veiligheidsnommer", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Boodskap", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Bekyk veiligheidsnommer", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Kon nie telefoonnommer herroep nie. Kontroleer jou verbinding en probeer weer.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Wysigings kan slegs aangebring word binne 3 uur vanaf die tyd wat jy hierdie boodskap gestuur het.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Wysigings kan slegs aangebring word binne 24 uur vanaf die tyd wat jy hierdie boodskap gestuur het.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Hierdie boodskap is geskrap.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Aanhegsel te groot om te vertoon.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Sommige aanhegsels is te groot om te vertoon.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Kan nie detail van skenking herroep nie", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Slegs Signal-beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Wysiging van boodskappe is slegs vir Signal-beta-gebruikers beskikbaar. Indien jy 'n boodskap wysig, sal dit slegs sigbaar wees vir mense wat op die jongste weergawe van Signal-beta is.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Wysig boodskap", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Indien jy 'n boodskap wysig, sal dit slegs sigbaar wees vir mense wat op die jongste weergawes van Signal is. Hulle sal kan sien dat jy 'n boodskap gewysig het.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Inkomende video-oproep
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Uitgaande stemoproep", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Uitgaande video-oproep", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} is besig om jou te skakel", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Besig om te herkonnekteer
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} mens} other {{count,number} mense}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Oudio-oproep", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "BeĂ«indig", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Verlaat", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofoon afgeskakel", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofoon aangeskakel", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Lui aangeskakel", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Lui afgeskakel", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Instellings", @@ -3468,13 +3668,25 @@ "messageformat": "Volskermoproep", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Verander na rooster-skermbeeld", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Verander uitleg", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Verander na spreker-skermbeeld", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Roosteruitleg", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Sykolom-uitleg", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Sprekeruitleg", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Uitleg opgedateer", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Verlaat oproep", @@ -3576,6 +3788,14 @@ "messageformat": "Goed", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Kan nie boodskap wysig nie", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Slegs {max,number} wysigings kan aan hierdie boodskap aangebring word.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Jammer, daardie sgnl:// skakel het nie sin gemaak nie!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Gebruikersnaam", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Iets het verkeerd geloop met jou gebruikernaam, dit is nie meer aan jou rekening toegewys nie.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Skrap gebruikernaam", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Skep gebruikernaam", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-kode of skakel", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Gebruikernaam moet teruggestel word", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Gebruikernaamskakel moet teruggestel word", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Deel jou gebruikersnaam", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Skrap gebruikernaam", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Dit sal jou gebruikernaam verwyder en ander mense sal dit kan gebruik. Is jy seker?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Dit sal jou gebruikersnaam verwyder en jou QR-kode en skakel deaktiveer. \"{username} \" sal beskikbaar wees vir ander mense om dit oor te neem. Is jy seker?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Jy sal nie meer stories kan deel of sien nie. Storiebywerkings wat jy onlangs gedeel het, sal ook uitgevee word.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Taal", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Taal", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Stelseltaal", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Soek deur tale", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Geen resultate vir \"{searchTerm}\" nie", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Stel", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Herlaai Signal om toe te pas", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Om die taal te verander, moet die toepassing herlaai word.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Herlaai", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Bywerking na weergawe {version} is beskikbaar", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Jou instellings kon nie gestoor word nie. Probeer asb. weer.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Boodskap", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Meer style", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Herstel", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Klaar", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Gebruikersnaam-skakelkleur, {index,number} van {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "As jy jou QR-kode terugstel, sal jou bestaande QR-kode en skakel nie meer werk nie.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Besig om skakel terug te stel
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-kode en skakel nie gestel nie. Gaan jou netwerkverbinding na en probeer weer.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Stel jou Signal-gebruikersnaam op", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "gewysig", + "messageformat": "Gewysig", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Stuur weer", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Meer aksies", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Oproepe", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nuwe oproep", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nuwe oproep", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Meer aksies", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Vee oproepgeskiedenis uit", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Vee oproepgeskiedenis uit?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Dit sal die hele oproepgeskiedenis permanent uitvee", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Vee uit", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Oproepgeskiedenis uitgevee", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klik om 'n oproep te sien of te begin", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Soek", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtreer volgens gemis", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Skakel aan of af", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Geen onlangse oproepe nie. Begin deur 'n vriend te bel.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Geen resultate vir \"{query}\" nie", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Inkomend", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Uitgaande", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Gemis", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Groepoproep", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Geen onlangse gesprekke nie.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Geen resultate vir \"{query}\" nie", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Uitgaande stemoproep} other {Inkomende stemoproep}}} Video {{direction, select, Outgoing {Uitgaande video-oproep} other {Inkomende video-oproep}}} Group {{direction, select, Outgoing {Uitgaande groepoproep} other {Inkomende groepoproep}}} other {{direction, select, Outgoing {Uitgaande oproep} other {Inkomende oproep}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Gemiste stemoproep} Video {Gemiste video-oproep} Group {Gemiste groepoproep} other {Gemiste oproep}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Onbeantwoorde stemoproep} Video {Onbeantwoorde video-oproep} Group {Onbeantwoorde groepoproep} other {Onbeantwoorde oproep}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Stemoproep geweier} Video {Video-oproep geweier} Group {Groepoproep geweier} other {Oproep geweier}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ander persoon is besig om te tik.} other {{count,number} ander persone is besig om te tik.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Wat is nuut", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Klein veranderings, foutregstellings en prestasieverbeterings. Dankie dat jy Signal gebruik!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Hierdie opdatering bevat 'n paar verbeterings vir stem- en video-oproepe, en 'n paar geringe dokumentasie-opdaterings (dankie, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Nou kan jy jou geselekteerde taal in Signal verander sonder om jou stelselinstellings te verander (Signal-instellings > Voorkoms > Taal)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Ons het sommige groepkennisgewingsikone opgedateer." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Ons het 'n kort vertraging reggemaak wat soms in macOS voorgekom het nadat daar by 'n oproep-wagkamer aangesluit is." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Ons het die oorgangsanimasie reggemaak vir videoteĂ«ls wanneer iemand by 'n groepoproep aansluit of dit verlaat." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Nou kan jy op 'n profielfoto of groepavatar in die kletsopskrif klik om vinnig toegang daartoe te verkry of te gaan kyk na enige stories van daardie klets wat jy nog nie gesien het nie. Dankie, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ar/messages.json b/_locales/ar/messages.json index 4c0d9140d7..7c960eb177 100644 --- a/_locales/ar/messages.json +++ b/_locales/ar/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Ű­ŰŻŰ« ۟۷ۣ في Ù‚Ű§ŰčŰŻŰ© Ű§Ù„ŰšÙŠŰ§Ù†Ű§ŰȘ", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ű­ŰŻŰ« ۟۷ۣ في Ù‚Ű§ŰčŰŻŰ© Ű§Ù„ŰšÙŠŰ§Ù†Ű§ŰȘ. يُمكنك Ù†ŰłŰź Ű§Ù„ŰźŰ·ŰŁ ÙˆŰ§Ù„Ű§ŰȘŰ”Ű§Ù„ ۚۯŰčم ŰłÙŠŰŹÙ†Ű§Ù„ Ù„Ù…ÙŰłŰ§ŰčŰŻŰȘك Űčلى Ű­Ù„ Ű§Ù„Ù…ŰŽÙƒÙ„Ű©. ۄ۰ۧ كنŰȘ في ۭۧۏ۩ Ű„Ù„Ù‰ ۧ۳ŰȘŰźŰŻŰ§Ù… ŰłÙŠŰŹÙ†Ű§Ù„ في Ű§Ù„Ű­ÙŠÙ†ŰŒ يُمكنك Ù…ŰłŰ­ ŰšÙŠŰ§Ù†Ű§ŰȘك ÙˆŰ„Űčۧۯ۩ Ű§Ù„ŰȘŰŽŰșيل.\n\nۧŰȘŰ”Ù„ ŰšŰ§Ù„ŰŻŰčم Űčۚ۱ ŰČÙŠŰ§Ű±Ű©: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Ù…ŰłŰ­ ŰŹÙ…ÙŠŰč Ű§Ù„ŰšÙŠŰ§Ù†Ű§ŰȘ Ű«Ù… Ű„Űčۧۯ۩ Ű§Ù„ŰȘŰŽŰșيل", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Ù…ŰłŰ­ Ű§Ù„ŰšÙŠŰ§Ù†Ű§ŰȘ Ű«Ù… Ű„Űčۧۯ۩ Ű§Ù„ŰȘŰŽŰșيل", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Ù…ŰłŰ­ ŰŹÙ…ÙŠŰč Ű§Ù„ŰšÙŠŰ§Ù†Ű§ŰȘ Ù„Ù„ŰŁŰšŰŻŰŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ŰłÙŠÙŰ­Ű°Ù ŰłÙŰŹÙ„ Ű±ŰłŰ§ŰŠÙ„Ùƒ ÙˆŰ§Ù„ÙˆŰłŰ§ŰŠŰ· ŰšŰŽÙƒÙ„ Ù†Ù‡Ű§ŰŠÙŠ من Ù‡Ű°Ű§ Ű§Ù„ŰŹÙ‡Ű§ŰČ. ŰłŰȘŰȘمكّن من ۧ۳ŰȘŰźŰŻŰ§Ù… ŰłÙŠŰŹÙ†Ű§Ù„ Űčلى Ù‡Ű°Ű§ Ű§Ù„ŰŹÙ‡Ű§ŰČ ŰšŰčŰŻ Ű„Űčۧۯ۩ Ű±ŰšŰ·Ù‡. لن ÙŠÙŰ€ŰŻÙŠ Ù‡Ű°Ű§ Ű„Ù„Ù‰ Ű­Ű°Ù ŰŁÙŠ ŰšÙŠŰ§Ù†Ű§ŰȘ من Ù‡Ű§ŰȘفك.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Ù„Ű§ يŰȘŰ·Ű§ŰšÙ‚ ۄ۔ۯۧ۱ Ù‚Ű§ŰčŰŻŰ© ŰšÙŠŰ§Ù†Ű§ŰȘك مŰč ۄ۔ۯۧ۱ ŰłÙŠŰŹÙ†Ű§Ù„ Ù‡Ű°Ű§. ŰȘŰŁÙƒŰŻ من فŰȘŰ­ ŰŁŰ­ŰŻŰ« ۄ۔ۯۧ۱ Ù„ÙŰłÙŠŰŹÙ†Ű§Ù„ Űčلى Ű­Ű§ŰłÙˆŰšÙƒ.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ملف", @@ -300,6 +316,70 @@ "messageformat": "Ű§Ù„ŰŻŰ±ŰŻŰŽŰ§ŰȘ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Ű­ŰŻŰ«ŰȘ Ù…ŰŽÙƒÙ„Ű© مŰč Ű§ŰłÙ… Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙ… Ű§Ù„ŰźŰ§Ű” ŰšÙƒ ولم يŰčÙŰŻ Ù…ŰźŰ”Ű”Ù‹Ű§ Ù„Ű­ŰłŰ§ŰšÙƒ. يمكنك Ù…Ű­Ű§ÙˆÙ„Ű© ŰȘŰčيينه من ŰŹŰŻÙŠŰŻ ŰŁÙˆ ۧ۟ŰȘÙŠŰ§Ű± Ű§ŰłÙ… Ù…ÙŰłŰȘŰźŰŻÙ… ŰŹŰŻÙŠŰŻ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Ű„Ű”Ù„Ű§Ű­ Ű§Ù„ŰąÙ†", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Ű­ŰŻŰ« ۟۷ۣ Ù…Ű§ مŰč Ű±Ù…ŰČ Ű§Ù„Ű§ŰłŰȘۏۧۚ۩ Ű§Ù„ŰłŰ±ÙŠŰč ÙˆŰ±Ű§ŰšŰ· Ű§ŰłÙ… Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙ… Ű§Ù„ŰźŰ§Ű”ÙŠÙ† ŰšÙƒŰŒ Ű­ÙŠŰ« لم يŰčŰŻ Ű”Ű§Ù„Ű­Ù‹Ű§. ŰŁÙ†ŰŽŰŠ Ű±Ű§ŰšŰ·Ù‹Ű§ ŰŹŰŻÙŠŰŻÙ‹Ű§ Ù„Ù„Ù…ŰŽŰ§Ű±ÙƒŰ© مŰč Ű§Ù„ŰąŰźŰ±ÙŠÙ†.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Ű„Ű”Ù„Ű§Ű­ Ű§Ù„ŰąÙ†", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Űč۱۶ ŰčÙ„Ű§Ù…Ű§ŰȘ Ű§Ù„ŰȘŰšÙˆÙŠŰš", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ű„ŰźÙŰ§ŰĄ ŰčÙ„Ű§Ù…Ű§ŰȘ Ű§Ù„ŰȘŰšÙˆÙŠŰš", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ű­ŰŻŰ« ۟۷ۣ Ù…Ű§", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ŰșÙŠŰ± Ù…Ù‚Ű±ÙˆŰĄŰ©", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Ű”ÙÙ†Ù‘ÙŰȘ ŰșÙŠŰ± Ù…Ù‚Ű±ÙˆŰĄŰ©", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Ű§Ù„ŰŻŰ±ŰŻŰŽŰ§ŰȘ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű§ŰȘ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Ű§Ù„Ù‚ÙŰ”Ű”", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Ű§Ù„Ű„ŰčۯۧۯۧŰȘ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "‫ŰȘŰ­ŰŻÙŠŰ« ŰłÙŠŰŹÙ†Ű§Ù„â€Ź", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Ű§Ù„Ű±ŰŹÙˆŰč", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ű„Ù†Ù‘ÙŽ Ù‡Ű°Ù‡ Ű§Ù„ŰŻŰ±ŰŻŰŽŰ§ŰȘ Ù…Ű€Ű±ŰŽÙŰ© ÙˆŰłŰȘŰžÙ‡Ű± في ŰčÙ„ŰšŰ© Ű§Ù„ÙˆŰ§Ű±ŰŻ ۄ۰ۧ ŰȘمَّ ۧ۳ŰȘÙ„Ű§Ù… Ű±ŰłŰ§ŰŠÙ„ ŰŹŰŻÙŠŰŻŰ© ÙÙ‚Ű·.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ű§Ù„Ű§ŰȘŰ”Ű§Ù„ Űčلى كل Ű­Ű§Ù„", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Ű§Ù†Ű¶Ù… Űčلى ŰŁÙŠ Ű­Ű§Ù„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ۧ۳ŰȘŰŠÙ†Ű§Ù Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű©", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ŰŹŰ§Ű±Ù ŰȘŰ­ŰŻÙŠŰ« ŰŁŰ±Ù‚Ű§Ù… Ű§Ù„ŰŁÙ…Ű§Ù†.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "لمŰčŰ±ÙŰ© Ű§Ù„Ù…ŰČÙŠŰŻ", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Ű±Ù‚Ù… Ű§Ù„ŰŁÙ…Ű§Ù† Ű§Ù„ŰłŰ§ŰšÙ‚", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Ű±Ù‚Ù… Ű§Ù„ŰŁÙ…Ű§Ù† Ű§Ù„ŰȘŰ§Ù„ÙŠ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ۄ۔ۯۧ۱ Ű±Ù‚Ù… Ű§Ù„ŰŁÙ…Ű§Ù†ŰŒ {index,number} من ŰŁŰ”Ù„ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Űčلِّم كمُŰȘŰ­Ù‚Ù‘ÙŽÙ‚ منه", @@ -663,33 +747,41 @@ "messageformat": "Ù…Ű­Ùˆ Ű§Ù„ŰȘŰ­Ù‚Ù‘Ù‚", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "للŰȘŰ­Ù‚Ù‘Ù‚ من ŰŁÙ…Ű§Ù† Ű§Ù„ŰȘŰŽÙÙŠŰ± من Ű§Ù„Ű·Ű±Ù Ù„Ù„Ű·Ű±Ù مŰč {name}ی Ù‚Ű§Ű±Ù† Ű§Ù„ŰŁŰ±Ù‚Ű§Ù… ŰŁŰčÙ„Ű§Ù‡ ŰšŰŁŰŹÙ‡ŰČŰȘه. يُمكنه ŰŁÙŠŰ¶Ù‹Ű§ Ù…ŰłŰ­ Ű±Ù…ŰČك ۚۧ۳ŰȘŰźŰŻŰ§Ù… ŰŹÙ‡Ű§ŰČه.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "مŰčŰ±ÙŰ© Ű§Ù„Ù…ŰČÙŠŰŻ", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "للŰȘŰ­Ù‚Ù‘Ù‚ من ŰŁÙ…Ű§Ù† Ű§Ù„ŰȘŰŽÙÙŠŰ± من Ű§Ù„Ű·Ű±Ù Ù„Ù„Ű·Ű±Ù مŰč {name}ی ÙŠÙŰ±ŰŹÙ‰ Ù…Ű·Ű§ŰšÙ‚Ű© لون Ű§Ù„ŰšŰ·Ű§Ù‚Ű© ŰŁŰčÙ„Ű§Ù‡ مŰč ŰŹÙ‡Ű§ŰČه ÙˆÙ…Ù‚Ű§Ű±Ù†Ű© Ű§Ù„ŰŁŰ±Ù‚Ű§Ù…. ۄ۰ۧ ÙŰŽÙ„ ŰȘŰ·Ű§ŰšÙ‚Ù‡Ù…Ű§ŰŒ ÙŠÙŰ±ŰŹÙ‰ ŰȘۏ۱ۚ۩ ŰČÙˆŰŹ ۹۟۱ من ŰŁŰ±Ù‚Ű§Ù… Ű§Ù„ŰŁÙ…Ű§Ù†. ŰłÙŽŰȘŰ­ŰȘۧۏ Ű„Ù„Ù‰ ŰȘŰ·Ű§ŰšÙ‚ ŰČÙˆŰŹ ÙˆŰ§Ű­ŰŻ ÙÙ‚Ű·.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "للŰȘŰ­Ù‚Ù‘Ù‚ من ŰŁÙ…Ű§Ù† Ű§Ù„ŰȘŰŽÙÙŠŰ± من Ű§Ù„Ű·Ű±Ù Ù„Ù„Ű·Ű±Ù مŰč {name}ی Ù‚Ű§Ű±Ù† Ű§Ù„ŰŁŰ±Ù‚Ű§Ù… ŰŁŰčÙ„Ű§Ù‡ ŰšŰŁŰŹÙ‡ŰČŰȘه. يُمكنه ŰŁÙŠŰ¶Ù‹Ű§ Ù…ŰłŰ­ Ű±Ù…ŰČك ۚۧ۳ŰȘŰźŰŻŰ§Ù… ŰŹÙ‡Ű§ŰČه.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Ű§Ù„ŰȘŰșÙŠÙŠŰ±Ű§ŰȘ Ű§Ù„ŰȘي ŰłŰȘ۷۱ۣ Űčلى ŰŁŰ±Ù‚Ű§Ù… Ű§Ù„ŰŁÙ…Ű§Ù†", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "يŰȘم ŰȘŰ­ŰŻÙŠŰ« ŰŁŰ±Ù‚Ű§Ù… Ű§Ù„ŰŁÙ…Ű§Ù† Űčلى Ù…ŰŻÙ‰ فŰȘ۱۩ Ű§Ù†ŰȘÙ‚Ű§Ù„ÙŠŰ© لŰȘفŰčيل ميŰČۧŰȘ Ű§Ù„ŰźŰ”ÙˆŰ”ÙŠŰ© Ű§Ù„Ù‚Ű§ŰŻÙ…Ű© في ŰłÙŠŰŹÙ†Ű§Ù„-Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "للŰȘŰ­Ù‚Ù‘Ù‚ من ŰŁŰ±Ù‚Ű§Ù… Ű§Ù„ŰŁÙ…Ű§Ù†ŰŒ ÙŠÙŰ±ŰŹÙ‰ Ù…Ű·Ű§ŰšÙ‚Ű© لون Ű§Ù„ŰšŰ·Ű§Ù‚Ű© مŰč ŰŹÙ‡Ű§ŰČ ŰŹÙ‡Ű© ۧŰȘŰ”Ű§Ù„Ùƒ. ۄ۰ۧ ÙŰŽÙ„ ŰȘŰ·Ű§ŰšÙ‚Ù‡Ù…Ű§ŰŒ ÙŠÙŰ±ŰŹÙ‰ ŰȘۏ۱ۚ۩ ŰČÙˆŰŹ ۹۟۱ من ŰŁŰ±Ù‚Ű§Ù… Ű§Ù„ŰŁÙ…Ű§Ù†. ŰłŰȘŰ­ŰȘۧۏ Ű„Ù„Ù‰ ŰȘŰ·Ű§ŰšÙ‚ ŰČÙˆŰŹ ÙˆŰ§Ű­ŰŻ ÙÙ‚Ű·.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ۭۚۧۏ۩ Ű„Ù„Ù‰ Ù…ŰłŰ§ŰčŰŻŰ© ۟", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Űčُلم", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ŰłÙŠŰȘم Ű„Ù†ŰŽŰ§ŰĄ Ű±Ù‚Ù… ŰŁÙ…Ű§Ù† مŰč Ù‡Ű°Ű§ Ű§Ù„ŰŽŰźŰ” ŰšŰčŰŻ ŰȘŰšŰ§ŰŻÙ„ Ű§Ù„Ű±ŰłŰ§ŰŠÙ„ مŰčه.", @@ -1267,10 +1359,6 @@ "messageformat": "Ű±Ű€ÙŠŰ© Ű§Ù„ÙˆŰłŰ§ŰŠŰ· Ű§Ù„Ű­ŰŻÙŠŰ«Ű©", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "للŰȘŰ­Ù‚Ù‘Ù‚ من ŰŁÙ…Ű§Ù† Ű§Ù„ŰȘŰŽÙÙŠŰ± من Ű§Ù„Ű·Ű±Ù Ù„Ù„Ű·Ű±Ù مŰč {name}ی Ù‚Ű§Ű±Ù† Ű§Ù„ŰŁŰ±Ù‚Ű§Ù… ŰŁŰčÙ„Ű§Ù‡ ŰšŰŁŰŹÙ‡ŰČŰȘه. يُمكنه ŰŁÙŠŰ¶Ù‹Ű§ Ù…ŰłŰ­ Ű§Ù„Ű±Ù…ŰČ Ű§Ù„Ù…ÙŰ±ŰšŰč ŰŁŰčÙ„Ű§Ù‡.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "لم يŰȘم ŰȘŰšŰ§ŰŻÙ„ ŰŁÙŠÙ‘Ű© Ű±ŰłŰ§ŰŠÙ„ مŰč Ù‡Ű°Ű§ Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ… Ű­ŰȘى Ű§Ù„ŰąÙ†. ŰłÙŠŰžÙ‡Ű± Ű±Ù‚Ù… ŰŁÙ…Ű§Ù†Ùƒ مŰčه ŰšŰčŰŻ Ű„Ű±ŰłŰ§Ù„ ŰŁÙˆÙ„ Ű±ŰłŰ§Ù„Ű©." }, @@ -1334,17 +1422,17 @@ "messageformat": "مŰčÙ„ÙˆÙ…Ű§ŰȘ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Ű­Ű°Ù", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Ű­Ű°Ù Ű§Ù„Ű±ŰłŰ§ŰŠÙ„", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Ű­Ű°Ù Ű§Ù„ŰŻŰ±ŰŻŰŽŰ©ŰŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Ű­Ű°Ù Ű§Ù„Ű±ŰłŰ§ŰŠÙ„ŰŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ŰłŰȘÙŰ­Ű°ÙŽÙ Ù‡Ű°Ù‡ Ű§Ù„ŰŻŰ±ŰŻŰŽŰ© من Ù‡Ű°Ű§ Ű§Ù„ŰŹÙ‡Ű§ŰČ.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ŰłŰȘÙŰ­Ű°ÙŽÙ Ű±ŰłŰ§ŰŠÙ„ Ù‡Ű°Ù‡ Ű§Ù„Ù…Ű­Ű§ŰŻŰ«Ű© من Ù‡Ű°Ű§ Ű§Ù„ŰŹÙ‡Ű§ŰČ. يُمكنك Ű§Ù„ŰšŰ­Ű« Űčن Ù‡Ű°Ù‡ Ű§Ù„ŰŻŰ±ŰŻŰŽŰ© ŰšŰčŰŻ Ű­Ű°Ù Ű§Ù„Ű±ŰłŰ§ŰŠÙ„.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "مŰșۧۯ۱۩ Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©", @@ -1438,6 +1526,14 @@ "messageformat": "ŰȘم ŰŻÙ…ŰŹ ŰłÙŰŹÙ„ Ű±ŰłŰ§ŰŠÙ„Ùƒ Ù„Ù„ŰŻŰ±ŰŻŰŽŰȘين مŰčۧ.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} يŰčÙˆŰŻ Ű„Ù„Ù‰ {conversationTitle}. ÙƒÙ„Ű§ÙƒÙÙ…Ű§ ŰčŰ¶Ùˆ في {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} يŰčÙˆŰŻ Ű„Ù„Ù‰ {conversationTitle}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Ű”ÙˆŰ±Ű© Ù…Ű”ŰșÙ‘Ű±Ű© Ù„Ù„Ű”ÙˆŰ±Ű© من Ű§Ù„Ű±ŰłŰ§Ù„Ű© Ű§Ù„Ù…Ù‚ŰȘۚ۳۩", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "مُŰčŰ§ÙˆŰŻŰ© Ű§Ù„Ű§ŰȘŰ”Ű§Ù„", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ۚۯۥ Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű©", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Ű§Ù„Ű§Ù†Ű¶Ù…Ű§Ù… Ù„Ù„Ù…ÙƒŰ§Ù„Ù…Ű©", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Ù„Ù‚ŰŻ ŰȘم كŰȘم Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ† ۚ۳ۚۚ ÙƒŰ«Ű±Ű© Ű§Ù„Ű­Ű§Ű¶Ű±ÙŠÙ† في Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű©", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ۄێŰčۧ۱ۧŰȘ Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű§ŰȘ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű© ممŰȘÙ„ŰŠŰ©", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Ű§Ù„ÙƒŰ§Ù…ÙŠŰ±Ű§", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Ű§Ù†Ű¶Ù…Ű§Ù…", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ۚۯۥ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű© مُمŰȘÙ„ŰŠŰ©", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Ű§Ù„ÙƒŰ§Ù…ÙŠŰ±Ű§ ŰșÙŠŰ± Ù…ŰŽŰșÙ„Ű©", @@ -1621,10 +1725,6 @@ "messageformat": "ŰŽŰșِّل Ű§Ù„ÙƒŰ§Ù…ÙŠŰ±Ű§", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "كŰȘم", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ† ŰșÙŠŰ± Ù…ŰŽŰșَّل", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ŰŽŰșِّل Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ†", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Ű§Ù„Ù…ÙŰŽŰ§Ű±ÙƒŰ©", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Ù†Ù…Ű· Ű§Ù„Űč۱۶ ŰșÙŠŰ± Ù…ŰŽŰșل", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Ű„ÙŠÙ‚Ű§Ù Ű§Ù„Űč۱۶", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ű±Ù†ÙŠÙ† Ű§Ù„Ű§ŰȘŰ”Ű§Ù„", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Ű„Ù† Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ© ÙƒŰšÙŠŰ±Ű© ۏۯۧ لكي ÙŠŰ±Ù† Ű§Ù„ŰȘŰ·ŰšÙŠÙ‚ Űčلى Ű§Ù„Ù…ŰŽŰ§Ű±ÙƒÙŠÙ†.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ŰȘفŰčيل Ű±Ù†ÙŠÙ† Ű§Ù„Ű§ŰȘŰ”Ű§Ù„", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Ű„ÙŠÙ‚Ű§Ù Ű§Ù„Ű±Ù†ÙŠÙ†", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ŰȘŰŽŰșيل Ű§Ù„Ű±Ù†ÙŠÙ†", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ŰźÙŠŰ§Ű±Ű§ŰȘ ŰŁÙƒŰ«Ű±", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ŰŁÙ†ŰȘ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Ű§Ù„ÙƒŰ§Ù…ÙŠŰ±Ű§ ŰșÙŠŰ± Ù…ŰŽŰșÙ„Ű©", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Űč۱۶ Ű±Ù‚Ù… Ű§ï»·Ù…Ű§Ù†", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Ù…Ű±Ű§ŰłÙ„Ű©", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Űč۱۶ Ű±Ù‚Ù… Ű§ï»·Ù…Ű§Ù†", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "â€«Ù„Ù‚ŰŻ ÙŰŽÙ„ ŰŹÙ„Űš Ű±Ù‚Ù… Ű§Ù„Ù‡Ű§ŰȘف. ÙŠÙŰ±ŰŹÙ‰ Ű§Ù„ŰȘŰŁÙƒŰŻ من ۧŰȘŰ”Ű§Ù„Ùƒ Ű«Ù… Ű§Ù„Ù…Ű­Ű§ÙˆÙ„Ű© Ù…Ű±Ű© ŰŁŰźŰ±Ù‰.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Ù„Ű§ يُمكن ۄۭۯۧ۫ Ű§Ù„ŰȘŰčŰŻÙŠÙ„Ű§ŰȘ Ű„Ù„Ű§ في ŰșŰ¶ÙˆÙ† 3 ۳ۧŰčۧŰȘ من وقŰȘ Ű„Ű±ŰłŰ§Ù„ Ù‡Ű°Ù‡ Ű§Ù„Ű±ŰłŰ§Ù„Ű©.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Ù„Ű§ يُمكن ۄۭۯۧ۫ Ű§Ù„ŰȘŰčŰŻÙŠÙ„Ű§ŰȘ Ű„Ù„Ű§Ù‘ في ŰșŰ¶ÙˆÙ† 24 ۳ۧŰčŰ© من وقŰȘ Ű„Ű±ŰłŰ§Ù„ Ù‡Ű°Ù‡ Ű§Ù„Ű±ŰłŰ§Ù„Ű©.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ù„Ù‚ŰŻ Ű­ÙŰ°ÙÙŽŰȘ Ù‡Ű°Ù‡ Ű§Ù„Ű±ŰłŰ§Ù„Ű©.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ŰȘŰčŰ°Ù‘Ű± Ű„ŰžÙ‡Ű§Ű± Ű§Ù„Ù…ÙŰ±ÙÙ‚ Ù„ŰŁÙ† Ű­ŰŹÙ…Ù‡ ÙƒŰšÙŠŰ± ŰŹŰŻÙ‹Ű§.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ŰšŰč۶ Ű§Ù„Ù…ÙŰ±ÙÙ‚Ű§ŰȘ ÙƒŰšÙŠŰ±Ű© ŰŹŰŻÙ‹Ű§ Ù„Ű„ŰžÙ‡Ű§Ű±Ù‡Ű§.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ŰȘŰčŰ°Ù‘Ű± Ű§Ù„ŰšŰ­Ű« Űčن مŰčÙ„ÙˆÙ…Ű§ŰȘ Ű§Ù„ŰȘŰšŰ±Ù‘Űč", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ۄ۔ۯۧ۱ ŰłÙŠŰŹÙ†Ű§Ù„ Ű§Ù„ŰȘŰŹŰ±ÙŠŰšÙŠ ÙÙ‚Ű·", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ŰȘŰčŰŻÙŠÙ„ Ű§Ù„Ű±ŰłŰ§ŰŠÙ„ مُŰȘۭۧ Ù„Ù…ÙŰłŰȘŰźŰŻÙ…ÙŠ ۄ۔ۯۧ۱ ŰłÙŠŰŹÙ†Ű§Ù„ Ű§Ù„ŰȘŰŹŰ±ÙŠŰšÙŠ ÙÙ‚Ű·. ۄ۰ۧ قمŰȘ ŰšŰȘŰčŰŻÙŠÙ„ Ű±ŰłŰ§Ù„Ű©ŰŒ فلن ŰȘكون مŰȘۭۧ۩ Ű„Ù„Ű§ Ù„Ù„ŰŁŰŽŰźŰ§Ű” Ű§Ù„Ű°ÙŠÙ† ÙŠŰłŰȘŰźŰŻÙ…ÙˆÙ† ŰŁŰ­ŰŻŰ« ۄ۔ۯۧ۱ ŰłÙŠŰŹÙ†Ű§Ù„ Ű§Ù„ŰȘŰŹŰ±ÙŠŰšÙŠ.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ŰȘŰčŰŻÙŠÙ„ Ű§Ù„Ű±ŰłŰ§Ù„Ű©", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ۄ۰ۧ قُمŰȘ ŰšŰȘŰčŰŻÙŠÙ„ Ű±ŰłŰ§Ù„Ű©ŰŒ فلن ÙŠŰžÙ‡Ű± Ű„Ù„Ű§ Ù„Ù„ŰŁŰŽŰźŰ§Ű” Ű§Ù„Ű°ÙŠÙ† ÙŠŰłŰȘŰźŰŻÙ…ÙˆÙ† ŰŁŰ­ŰŻŰ« ۄ۔ۯۧ۱ ŰłÙŠŰŹÙ†Ű§Ù„. ŰłÙŽÙŠŰȘمكنون من Ű±Ű€ÙŠŰ© ŰŁÙ†Ùƒ قمŰȘ ŰšŰȘŰčŰŻÙŠÙ„ Ű±ŰłŰ§Ù„Ű©.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© ŰšŰ§Ù„Ű”ÙˆŰ±Ű© ÙˆŰ§Ű±ŰŻŰ©â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ© ۔ۧۯ۱۩", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© ÙÙŠŰŻÙŠÙˆ ۔ۧۯ۱۩", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "Ù‡Ù†Ű§Ùƒ ۧŰȘŰ”Ű§Ù„ ŰšÙƒ من {ringer}", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ŰŹŰ§Ű±Ù Ű„Űčۧۯ۩ Ű§Ù„Ű§ŰȘŰ”Ű§Ù„â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "ŰłÙŠŰŹÙ†Ű§Ù„ {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, zero {Ù„Ű§ ŰŁŰ­ŰŻ ({count,number})} one {ێ۟۔ ÙˆŰ§Ű­ŰŻ ({count,number})} two {ŰŽŰźŰ”Ű§Ù† ({count,number})} few {{count,number} ŰŁÙŰ±Ű§ŰŻ} many {{count,number} ÙŰ±ŰŻŰ§} other {{count,number} ÙŰ±ŰŻ}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ©", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Ù†Ù‡Ű§ÙŠŰ©", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "مŰșۧۯ۱۩", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ† ŰșÙŠŰ± مفŰčل", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ† مفŰčل", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ŰȘم ŰȘفŰčيل Ű§Ù„Ű±Ù†ÙŠÙ†", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ŰȘم Ű„ÙŠÙ‚Ű§Ù Ű§Ù„Ű±Ù†ÙŠÙ†", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Ű§Ù„Ű„ŰčۯۧۯۧŰȘ", @@ -3468,13 +3668,25 @@ "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© ŰšÙ…Ù„ŰĄ Ű§Ù„ŰŽŰ§ŰŽŰ©", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Ű§Ù„ŰȘŰšŰŻÙŠÙ„ Ű„Ù„Ù‰ Űč۱۶ Ű§Ù„ŰŽŰšÙƒŰ©", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ŰȘŰșÙŠÙŠŰ± Ű·Ű±ÙŠÙ‚Ű© Ű§Ù„Űč۱۶", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Ű§Ù„ŰȘŰšŰŻÙŠÙ„ Ű„Ù„Ù‰ Ű§Ù„Ù…ŰȘŰ­ŰŻŰ«", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Űč۱۶ ŰŽŰšÙƒÙŠ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Űč۱۶ ŰšŰ·Ű±ÙŠÙ‚Ű© Ű§Ù„ŰŽŰ±ÙŠŰ· Ű§Ù„ŰŹŰ§Ù†ŰšÙŠ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Űč۱۶ Ű§Ù„Ù…ÙŰȘŰ­ŰŻŰ«", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ŰȘم ŰȘŰ­ÙŠÙŠÙ† Ű·Ű±ÙŠÙ‚Ű© Ű§Ù„Űč۱۶", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "مŰșۧۯ۱۩ Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű©", @@ -3576,6 +3788,14 @@ "messageformat": "Ű­ŰłÙ†Ű§", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ŰȘŰčŰ°Ù‘Ű± ŰȘŰčŰŻÙŠÙ„ Ű§Ù„Ű±ŰłŰ§Ù„Ű©", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "يُمكن ŰȘŰ·ŰšÙŠÙ‚ {max,number} ŰȘŰčŰŻÙŠÙ„Ù‹Ű§ ÙÙ‚Ű· Űčلى Ù‡Ű°Ù‡ Ű§Ù„Ű±ŰłŰ§Ù„Ű©.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "‫ŰčŰ°Ű±Ű§ŰŒ لكن ÙˆŰ”Ù„Ű© sgnl://‎ ÙƒÙ‡Ű°Ù‡ Ù„Ű§ مŰčنى Ù„Ù‡Ű§ !‬", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Ű§ÙŰłÙ…Ù Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙÙ…", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Ű­ŰŻŰ«ŰȘ Ù…ŰŽÙƒÙ„Ű© مŰč Ű§ŰłÙ… Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙ… Ű§Ù„ŰźŰ§Ű” ŰšÙƒ ولم يŰčÙŰŻ Ù…ŰźŰ”Ű”Ù‹Ű§ Ù„Ű­ŰłŰ§ŰšÙƒ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Ű­Ű°Ù Ű§ŰłÙ… Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ…", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ŰŁÙ†ŰŽÙŠŰĄ Ű§ŰłÙ… Ù…ÙŰłŰȘŰźŰŻÙÙ…", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Ű±Ù…ŰČ ŰŁÙˆ ۱ۧۚ۷ Ű§Ù„Ű§ŰłŰȘۏۧۚ۩ Ű§Ù„ŰłŰ±ÙŠŰč", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ÙŠŰŹŰš Ű„Űčۧۯ۩ ŰȘŰčيين Ű§ŰłÙ… Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ…", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ÙŠÙŽŰŹŰš Ű„Űčۧۯ۩ ŰȘŰčيين ۱ۧۚ۷ Ű§ŰłÙ… Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ…", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ŰŽŰ§Ű±Ùƒ Ű§ŰłÙ… Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙ… Ű§Ù„ŰźŰ§Ű” ŰšÙƒ", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Ű­Ű°Ù Ű§ŰłÙ… Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ…", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ŰłÙŽÙŠŰ­Ű°Ù Ű°Ù„Ùƒ Ű§ŰłÙ… Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ… Ű§Ù„ŰźŰ§Ű” ŰšÙƒŰŒ Ù…Ù…Ű§ ÙŠŰłÙ…Ű­ Ù„Ù„Ù…ÙŰłŰȘŰźŰŻÙ…ÙŠÙ† Ű§Ù„ŰąŰźŰ±ÙŠÙ† ۚۧ۳ŰȘŰźŰŻŰ§Ù…Ù‡. هل ŰŁÙ†ŰȘ مŰȘŰŁÙƒŰŻŰŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ŰłÙŠÙŰ€ŰŻÙŠ Ù‡Ű°Ű§ Ű„Ù„Ù‰ Ű„ŰČŰ§Ù„Ű© Ű§ŰłÙ… Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙ… Ű§Ù„ŰźŰ§Ű” ŰšÙƒ وŰȘŰčŰ·ÙŠÙ„ Ű±Ù…ŰČ Ű§Ù„Ű§ŰłŰȘۏۧۚ۩ Ű§Ù„ŰłŰ±ÙŠŰč ÙˆŰ§Ù„Ű±Ű§ŰšŰ· Ű§Ù„ŰźŰ§Ű”ÙŠÙ† ŰšÙƒ. \"{username}\" ŰłÙŠÙŰ”ŰšŰ­ مŰȘŰ§Ű­Ù‹Ű§ Ù„Ù„ŰąŰźŰ±ÙŠÙ† Ù„ÙŠŰłŰȘÙÙŠŰŻÙˆŰ§ منه. هل ŰŁÙ†ŰȘ مŰȘŰŁÙƒŰŻŰŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "لن ŰȘŰȘمكن من Ù…ŰŽŰ§Ű±ÙƒŰ© Ű§Ù„Ù‚ÙŰ”Ű” ŰŁÙˆ Ù…ÙŰŽÙŽŰ§Ù‡ŰŻŰ§ŰȘÙ‡Ű§ ŰšŰčŰŻ Ű§Ù„ŰąÙ†. ÙˆŰłÙŠŰȘم ŰŁÙŠŰ¶Ù‹Ű§ Ű­Ű°Ù ŰȘŰ­ŰŻÙŠŰ«Ű§ŰȘ Ű§Ù„Ù‚Ű”Ű© Ű§Ù„ŰȘي ŰŽŰ§Ű±ÙƒŰȘÙ‡Ű§ Ù…Ű€ŰźŰ±Ù‹Ű§.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Ű§Ù„Ù„ŰșŰ©", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Ű§Ù„Ù„ŰșŰ©", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "لŰșŰ© Ű§Ù„Ù†ŰžŰ§Ù…", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Ű§Ù„ŰšŰ­Ű« Űčن Ű§Ù„Ù„ŰșۧŰȘ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Ù„Ű§ ŰȘÙˆŰŹŰŻ نŰȘÙŠŰŹŰ© لـ \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ŰȘŰčيين", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Ű„Űčۧۯ۩ ŰȘŰŽŰșيل ŰłÙŠŰŹÙ†Ű§Ù„ للŰȘŰ·ŰšÙŠÙ‚", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "لŰȘŰșÙŠÙŠŰ± Ű§Ù„Ù„ŰșŰ©ŰŒ ÙŠŰŹŰš Ű„Űčۧۯ۩ ŰȘŰŽŰșيل Ű§Ù„ŰȘŰ·ŰšÙŠÙ‚.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ű„Űčۧۯ۩ Ű§Ù„ŰȘŰŽŰșيل", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Ű„Ù† ۧï»č۔ۯۧ۱ {version} مŰȘۭۧ Ű­Ű§Ù„ÙŠŰ§", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Ù„Ù‚ŰŻ Ű­ŰŻŰ« ۟۷ۣ ŰŁŰ«Ù†Ű§ŰĄ Ű­ÙŰž Ű„ŰčۯۧۯۧŰȘك. ÙŠÙŒŰ±ŰŹÙ‰ Ű§Ù„Ù…Ű­Ű§ÙˆÙ„Ű© Ù„Ű§Ű­Ù‚Ű§.‏", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Ù…Ű±Ű§ŰłÙ„Ű©", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Ű§Ù„Ù…ŰČÙŠŰŻ من Ű§Ù„ŰŁÙ†Ù…Ű§Ű·", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Ű„Űčۧۯ۩ Ű§Ù„ŰȘŰčيين", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ŰȘمّ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "لون ۱ۧۚ۷ Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ…ŰŒ {index,number} من {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ۄ۰ۧ قمŰȘ ۚۄŰčۧۯ۩ ŰȘŰčيين Ű±Ù…ŰČ Ű§Ù„Ű§ŰłŰȘۏۧۚ۩ Ű§Ù„ŰłŰ±ÙŠŰč Ű§Ù„ŰźŰ§Ű” ŰšÙƒŰŒ فلن يŰčمل Ű±Ù…ŰČ Ű§Ù„Ű§ŰłŰȘۏۧۚ۩ ÙˆŰ§Ù„Ű±Ű§ŰšŰ· Ű§Ù„ŰźŰ§Ű”ÙŠÙ† ŰšÙƒ ŰšŰčŰŻÙ‡Ű§.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Ű„Űčۧۯ۩ ŰȘŰčيين Ű§Ù„Ű±Ű§ŰšŰ·â€Š", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "لم يŰȘم ŰȘŰčيين Ű±Ù…ŰČ ÙˆŰ±Ű§ŰšŰ· Ű§Ù„Ű§ŰłŰȘۏۧۚ۩ Ű§Ù„ŰłŰ±ÙŠŰč. ŰȘŰ­Ù‚Ù‘Ù‚ من ۧŰȘŰ”Ű§Ù„Ùƒ ŰšŰ§Ù„Ű„Ù†ŰȘŰ±Ù†ŰȘ ÙˆŰ­Ű§ÙˆÙ„ Ù…Ű±Ű© ŰŁŰźŰ±Ù‰.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Ű„Űčۯۧۯ Ű§ÙŰłÙ… Ű§Ù„Ù…ÙŰłŰȘŰźŰŻÙÙ… Ű§Ù„ŰźŰ§Ű” ŰšÙƒ Űčلى ŰłÙŠŰŹÙ†Ű§Ù„", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "Ű„Űčۧۯ۩ Ű§Ù„Ű„Ű±ŰłŰ§Ù„", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ۄۏ۱ۧۥۧŰȘ ŰŁŰźŰ±Ù‰", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű§ŰȘ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹŰŻÙŠŰŻŰ©", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹŰŻÙŠŰŻŰ©", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ۄۏ۱ۧۥۧŰȘ ŰŁŰźŰ±Ù‰", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Ù…ŰłŰ­ ŰłÙ‘ÙŰŹÙÙ„Ù‘ Ű§Ù„Ű§ŰȘŰ”Ű§Ù„Ű§ŰȘ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Ù…ŰłŰ­ ŰłÙ‘ÙŰŹÙÙ„Ù‘ Ű§Ù„Ű§ŰȘŰ”Ű§Ù„Ű§ŰȘ۟", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ŰłÙŠŰ€ŰŻÙŠ Ù‡Ű°Ű§ Ű„Ù„Ù‰ Ű­Ű°Ù ŰŹÙ…ÙŠŰč ŰłÙ‘ÙŰŹÙÙ„Ù‘ Ű§Ù„Ű§ŰȘŰ”Ű§Ù„Ű§ŰȘ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Ù…Ű­Ùˆ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "ŰȘم Ù…ŰłŰ­ ŰłÙ‘ÙŰŹÙÙ„Ù‘ Ű§Ù„Ű§ŰȘŰ”Ű§Ù„Ű§ŰȘ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Ű§Ù†Ù‚Ű± لŰč۱۶ ŰŁÙˆ ۚۯۥ Ù…ÙƒŰ§Ù„Ù…Ű©", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ۭۚ۫", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Ű§Ù„ÙÙ„ŰȘ۱۩ ۭ۳ۚ Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű§ŰȘ Ű§Ù„ÙŰ§ŰŠŰȘŰ©", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ŰȘŰšŰŻÙŠÙ„", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ù„Ű§ ŰȘÙˆŰŹŰŻ Ù…ÙƒŰ§Ù„Ù…Ű§ŰȘ Ű­ŰŻÙŠŰ«Ű©. ۧۚۯۣ ŰšŰ§Ù„Ű§ŰȘŰ”Ű§Ù„ ŰšŰ”ŰŻÙŠÙ‚.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Ù„Ű§ ŰȘÙˆŰŹŰŻ نŰȘÙŠŰŹŰ© لـ \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ÙˆŰ§Ű±ŰŻŰ©", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "۔ۧۯ۱۩", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ÙŰ§ŰŠŰȘŰ©", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű© Ű§Ù„ŰŹÙ…Ű§ŰčÙŠŰ©", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ù„Ű§ ŰȘÙˆŰŹŰŻ Ù…Ű­Ű§ŰŻŰ«Ű§ŰȘ Ű­ŰŻÙŠŰ«Ű©.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Ù„Ű§ ŰȘÙˆŰŹŰŻ نŰȘÙŠŰŹŰ© لـ \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ© ۔ۧۯ۱۩} other {Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ© ÙˆŰ§Ű±ŰŻŰ©}}} Video {{direction, select, Outgoing {Ù…ÙƒŰ§Ù„Ù…Ű© ÙÙŠŰŻÙŠÙˆ ۔ۧۯ۱۩} other {Ù…ÙƒŰ§Ù„Ù…Ű© ÙÙŠŰŻÙŠÙˆ ÙˆŰ§Ű±ŰŻŰ©}}} Group {{direction, select, Outgoing {Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹÙ…Ű§ŰčÙŠŰ© ۔ۧۯ۱۩} other {Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹÙ…Ű§ŰčÙŠŰ© ÙˆŰ§Ű±ŰŻŰ©}}} other {{direction, select, Outgoing {Ù…ÙƒŰ§Ù„Ù…Ű© ۔ۧۯ۱۩} other {Ù…ÙƒŰ§Ù„Ù…Ű© ÙˆŰ§Ű±ŰŻŰ©}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ© ÙŰ§ŰŠŰȘŰ©} Video {Ù…ÙƒŰ§Ù„Ù…Ű© ÙÙŠŰŻÙŠÙˆ ÙŰ§ŰŠŰȘŰ©} Group {Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹÙ…Ű§ŰčÙŠŰ© ÙŰ§ŰŠŰȘŰ©} other {Ù…ÙƒŰ§Ù„Ù…Ű© ÙŰ§ŰŠŰȘŰ©}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ© لم يŰȘم Ű§Ù„Ű±ŰŻ ŰčÙ„ÙŠÙ‡Ű§} Video {Ù…ÙƒŰ§Ù„Ù…Ű© ÙÙŠŰŻÙŠÙˆ لم يŰȘم Ű§Ù„Ű±ŰŻ ŰčÙ„ÙŠÙ‡Ű§} Group {Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹÙ…Ű§ŰčÙŠŰ© لم يŰȘم Ű§Ù„Ű±ŰŻ ŰčÙ„ÙŠÙ‡Ű§} other {Ù…ÙƒŰ§Ù„Ù…Ű© لم يŰȘم Ű§Ù„Ű±ŰŻ ŰčÙ„ÙŠÙ‡Ű§}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Ù…ÙƒŰ§Ù„Ù…Ű© Ű”ÙˆŰȘÙŠŰ© Ù…Ű±ÙÙˆŰ¶Ű©} Video {Ù…ÙƒŰ§Ù„Ù…Ű© ÙÙŠŰŻÙŠÙˆ Ù…Ű±ÙÙˆŰ¶Ű©} Group {Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹÙ…Ű§ŰčÙŠŰ© Ù…Ű±ÙÙˆŰ¶Ű©} other {Ù…ÙƒŰ§Ù„Ù…Ű© Ù…Ű±ÙÙˆŰ¶Ű©}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, zero {{count,number} ŰąŰźŰ±ÙˆÙ† يكŰȘŰšÙˆÙ†.} one {{count,number} ۹۟۱ يكŰȘŰš.} two {{count,number} ŰąŰźŰ±Ű§Ù† يكŰȘŰšŰ§Ù†.} few {{count,number} ŰąŰźŰ±ÙˆÙ† يكŰȘŰšÙˆÙ†.} many {{count,number} ŰąŰźŰ±ÙŠÙ† يكŰȘŰšÙˆÙ†.} other {{count,number} ŰąŰźŰ±ÙˆÙ† يكŰȘŰšÙˆÙ†.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Ù…Ű§ Ű§Ù„ŰŹŰŻÙŠŰŻ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ŰȘŰčŰŻÙŠÙ„Ű§ŰȘ Ű”ŰșÙŠŰ±Ű©ŰŒ ŰȘŰ”Ù„ÙŠŰ­ Ű§Ù„ŰŁŰčŰ·Ű§Ù„ŰŒ وŰȘŰ­ŰłÙŠÙ†Ű§ŰȘ Ù„Ù„ŰŁŰŻŰ§ŰĄ. ŰŽÙƒŰ±Ù‹Ű§ Űčلى ۧ۳ŰȘŰźŰŻŰ§Ù…ÙƒÙ… ŰłÙŠŰŹÙ†Ű§Ù„!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "يŰȘŰ¶Ù…Ù‘Ù† Ù‡Ű°Ű§ Ű§Ù„ŰȘŰ­ŰŻÙŠŰ« ŰšŰč۶ Ű§Ù„ŰȘŰ­ŰłÙŠÙ†Ű§ŰȘ Űčلى Ű§Ù„Ù…ÙÙƒŰ§Ù„Ù…Ű§ŰȘ Ű§Ù„Ű”ÙˆŰȘÙŠŰ© ÙˆÙ…ÙƒŰ§Ù„Ù…Ű§ŰȘ Ű§Ù„ÙÙŠŰŻÙŠÙˆŰŒ ÙˆŰšŰč۶ ŰȘŰ­ŰŻÙŠŰ«Ű§ŰȘ Ű§Ù„ÙˆŰ«Ű§ŰŠÙ‚ Ű§Ù„ŰšŰłÙŠŰ·Ű© (ŰŽÙƒŰ±Ù‹Ű§ŰŒ {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "يُمكنك Ű§Ù„ŰąÙ† ŰȘŰșÙŠÙŠŰ± لŰșŰȘك Ű§Ù„Ù…ÙŰźŰȘۧ۱۩ في ŰłÙŠŰŹÙ†Ű§Ù„ ŰŻÙˆÙ† ŰȘŰșÙŠÙŠŰ± لŰșŰ© Ű§Ù„Ù†ŰžŰ§Ù… (Ű„ŰčۯۧۯۧŰȘ ŰłÙŠŰŹÙ†Ű§Ù„ > Ű§Ù„Ù…ŰžÙ‡Ű± > Ű§Ù„Ù„ŰșŰ©)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Ù„Ù‚ŰŻ Ù‚Ù…Ù†Ű§ ŰšŰȘŰșÙŠÙŠŰ± ŰŁÙŠÙ‚ÙˆÙ†Ű§ŰȘ Ű§Ù„Ű„ŰŽŰčۧ۱ۧŰȘ Ű§Ù„ŰȘي ŰȘŰžÙ‡Ű± ŰšÙ…Ù†Ű§ŰłŰšŰ© ŰȘŰ­ŰŻÙŠŰ«Ű§ŰȘ Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©ŰŒ Ù…Ű«Ù„Ű§Ù‹ ŰčÙ†ŰŻ Ű§Ù†Ű¶Ù…Ű§Ù… ێ۟۔ ŰŹŰŻÙŠŰŻ Ű„Ù„Ù‰ Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©. ŰȘ۳ۧŰčŰŻ Ù‡Ű°Ù‡ Ű§Ù„ŰŁÙŠÙ‚ÙˆÙ†Ű§ŰȘ في ŰȘŰ­ŰłÙŠÙ† Ű§Ù„ÙˆŰ¶ÙˆŰ­ŰŒ ŰźŰ”ÙˆŰ”Ù‹Ű§ ۄ۰ۧ كنŰȘ ŰȘŰčÙŠŰŽ Ű§Ù„ŰžÙ„Ű§Ù… ŰšÙŰ¶Ù„ Ű§Ù„ÙˆŰ¶Űč Ű§Ù„Ù…ÙŰžÙ„Ù…. Ű§Ù„ŰŁÙŠÙ‚ÙˆÙ†Ű§ŰȘ Ű§Ù„Ù…Ű§Ű¶ÙŠŰ© ŰȘŰšÙ†Ù‘ŰȘ Ű§Ù„ŰžÙ„Ű§Ù… ÙÙ‚Ű·. Ù‡Ű°Ù‡ Ű§Ù„ŰŁÙŠÙ‚ÙˆÙ†Ű§ŰȘ Ű§Ù„ŰŹŰŻÙŠŰŻŰ© ÙˆÙ„ŰŻŰȘ فيه وŰȘ۱Űč۱ŰčŰȘ ŰŻŰ§ŰźÙ„Ù‡." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Ù„Ù‚ŰŻ ŰŁŰ”Ù„Ű­Ù†Ű§ ŰȘŰŁŰźÙŠŰ±Ù‹Ű§ Ù‚Ű”ÙŠŰ±Ù‹Ű§ ÙƒŰ§Ù† يقŰč ŰŁŰ­ÙŠŰ§Ù†Ű§ Űčلى ŰŁŰŹÙ‡ŰČŰ© macOS ŰčÙ†ŰŻ Ű§Ù„Ű§Ù†Ű¶Ù…Ű§Ù… Ű„Ù„Ù‰ Ű±ŰŻÙ‡Ű© ۧŰȘŰ”Ű§Ù„." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Ù„Ù‚ŰŻ ŰŁŰ”Ù„Ű­Ù†Ű§ Ű±ŰłÙ…Ű© Ű§Ù„Ű§Ù†ŰȘÙ‚Ű§Ù„ Ù„Ù…Ù‚Ű§Ű·Űč Ű§Ù„ÙÙŠŰŻÙŠÙˆ ŰčÙ†ŰŻÙ…Ű§ ÙŠÙ†Ű¶Ù… ێ۟۔ Ű„Ù„Ù‰ Ù…ÙƒŰ§Ù„Ù…Ű© ŰŹÙ…Ű§ŰčÙŠŰ© ŰŁÙˆ يŰșŰ§ŰŻŰ±Ù‡Ű§. ŰčÙ†ŰŻÙ…Ű§ ŰȘŰ±Ù‰ ÙˆŰŹÙ‡ Ű”ŰŻÙŠÙ‚ ÙŠŰžÙ‡Ű± في Ű§Ù„ŰčŰ±Ű¶ŰŒ ÙÙ‡Ű°Ù‡ Ű­Ű±ÙƒŰ© ۧۏŰȘÙ…Ű§ŰčÙŠŰ©." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "يمكنك Ű§Ù„ŰąÙ† Ű§Ù„Ù†Ù‚Ű± Űčلى Ű”ÙˆŰ±Ű© ۭ۳ۧۚ ŰŽŰźŰ”ÙŠ ŰŁÙˆ Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ù„Ù…ŰŹÙ…ÙˆŰčŰ© Ù…Ű§ في ŰčÙ†ÙˆŰ§Ù† Ű§Ù„ŰŻŰ±ŰŻŰŽŰ© Ù„Ù„ÙˆŰ”ÙˆÙ„ ۚ۳۱ŰčŰ© Ű„Ù„Ù‰ Ű„ŰčۯۧۯۧŰȘ Ű§Ù„ŰŻŰ±ŰŻŰŽŰ© ŰŁÙˆ Ù…ŰŽŰ§Ù‡ŰŻŰ© ŰŁÙŠ Ù‚Ű”Ű” لم ŰȘÙŰŽŰ§Ù‡ŰŻ من ŰȘلك Ű§Ù„ŰŻŰ±ŰŻŰŽŰ©. ŰŽÙƒŰ±Ù‹Ű§ŰŒ {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/az-AZ/messages.json b/_locales/az-AZ/messages.json index 8b4ab046b7..a23d2a1e22 100644 --- a/_locales/az-AZ/messages.json +++ b/_locales/az-AZ/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Verilənlər bazası xətası", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Məlumat bazası ilə əlaqəli xəta baß verdi. Xətanın surətini kĂ¶Ă§ĂŒrĂŒb, problemin həlli ĂŒĂ§ĂŒn Signal dəstək xidməti ilə əlaqə saxlaya bilərsiniz. Signal-dan elə indi istifadə etmək ĂŒĂ§ĂŒn verilənlərinizi silib yenidən baßladın.\n\n{link} keçidinə daxil olaraq dəstək xidməti ilə əlaqə saxlayın.", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "BĂŒtĂŒn verilənləri sil və yenidən baßlat", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Verilənləri silib yenidən baßladın", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "BĂŒtĂŒn verilənlər daimi olaraq silinsin?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "BĂŒtĂŒn mesaj tarixçəniz və media bu cihazdan daimi olaraq silinəcək. Signal-ı bu cihazda yenidən əlaqələndirdikdən sonra ondan istifadə edə bilərsiniz. Bu əməliyyat telefonunuzdan heç bir verilənləri silməyəcək.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Məlumat bazanızın versiyası Signal-ın bu versiyasına uyğun gəlmir. KompĂŒterinizdə Signal-ın ən son versiyasını açdığınızdan əmin olun.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fayl", @@ -300,6 +316,70 @@ "messageformat": "Çatlar", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "İstifadəçi adınızla bağlı xəta yarandı, o artıq hesabınıza təyin edilməyib. Onu yenidən quraßdırmağa cəhd edə və ya yenisini seçə bilərsiniz.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "İndi dĂŒzəlt", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "QR kodunuz və istifadəçi adınızın keçidində bir xəta baß verdi, o artıq etibarlı deyil. Baßqaları ilə paylaßmaq ĂŒĂ§ĂŒn yeni bir keçid yaradın.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "İndi dĂŒzəlt", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Tabları göstər", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Tabları gizlət", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Bir xəta baß verdi", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} oxunmamıß", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Oxunmamıß kimi ißarələndi", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Çatlar", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Zənglər", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Hekayələr", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Tənzimləmələr", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal-ı yenilə", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Geri", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Bu çatlar arxivləƟdirildi və yalnız yeni mesaj alındıqda \"Gələnlər\" qutusunda görĂŒnəcək.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Yenə də zəng et", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Yenə də qoßul", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Zəngə davam et", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "TəhlĂŒkəsizlik nömrələri yenilənir.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Daha ətraflı", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Əvvəlki təhlĂŒkəsizlik nömrəsi", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Növbəti təhlĂŒkəsizlik nömrəsi", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "TəhlĂŒkəsizlik nömrəsi versiyası, {total,number} / {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Təsdiqləndi olaraq ißarələ", @@ -663,33 +747,41 @@ "messageformat": "Təsdiqləməni təmizlə", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} ilə olan ucdan-uca ßifrələməni yoxlamaq ĂŒĂ§ĂŒn yuxarıdakı nömrələri onun cihazı ilə mĂŒqayisə edin. O kodunuzu öz cihazı ilə skan da edə bilər.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Daha ətraflı", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} ilə olan ucdan-uca ßifrələməni yoxlamaq ĂŒĂ§ĂŒn yuxarıdakı rəngli kartda görĂŒnən nömrəni istifadəçinin cihazı ilə mĂŒqayisə edin. Bu nömrə uyğun gəlmirsə baßqa bir təhlĂŒkəsizlik nömrəsini yoxlayın. Yalnız bir cĂŒt rəqəm mĂŒqayisə edilməlidir.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} ilə olan ucdan-uca ßifrələməni yoxlamaq ĂŒĂ§ĂŒn yuxarıdakı nömrələri onun cihazı ilə mĂŒqayisə edin. O kodunuzu öz cihazı ilə skan da edə bilər.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "TəhlĂŒkəsizlik nömrələrində dəyißikliklər", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal-dakı növbəti məxfilik xĂŒsusiyyətlərini aktivləƟdirmək ĂŒĂ§ĂŒn ötĂŒrmə mĂŒddətində təhlĂŒkəsizlik nömrələri yenilənir.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "TəhlĂŒkəsizlik nömrələrini yoxlamaq ĂŒĂ§ĂŒn rəngli kartda görĂŒnən rəqəmləri kontaktınızın cihazı ilə mĂŒqayisə edin. Bu nömrə uyğun gəlmirsə baßqa bir təhlĂŒkəsizlik nömrəsini yoxlayın. Yalnız bir cĂŒt rəqəmi mĂŒqayisə etmək tələb olunur.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Kömək lazımdır?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Anladım", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Bu Ɵəxsə aid təhlĂŒkəsizlik nömrəsi siz onunla mesajlaßmağa baßladıqdan sonra yaradılacaq.", @@ -1267,10 +1359,6 @@ "messageformat": "Son mediaya bax", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} ilə olan ucdan-uca ßifrələməni yoxlamaq ĂŒĂ§ĂŒn yuxarıdakı nömrəni onun cihazı ilə mĂŒqayisə edin. O, həmçinin yuxarıdakı QR kodunu da skan edə bilər.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Hələ ki, bu əlaqə ilə mesajlaßmadınız. GĂŒvənlik nömrəsi, ilk mesajdan sonra mövcud olacaq." }, @@ -1334,17 +1422,17 @@ "messageformat": "Məlumat", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Sil", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Mesajları sil", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Çat silinsin?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Mesajlar silinsin?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Bu söhbət bu cihazdan silinəcək.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Bu çatda olan mesajlar bu cihazdan silinəcək. Mesajları sildikdən sonra da bu çata daxil ola bilərsiniz.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Qrupu tərk et", @@ -1438,6 +1526,14 @@ "messageformat": "Hər iki çatdan olan mesaj tarixçəniz burada birləƟdirilib.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} nömrəsi {conversationTitle} adlı istifadəçiyə aiddir. Hər ikiniz də {sharedGroup} qrupunun ĂŒzvĂŒsĂŒnĂŒz.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} nömrəsi {conversationTitle} adlı istifadəçiyə aiddir.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Sitat mesajdan təsvirin eskizi", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Yenidən zəng et", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Zəng baßlat", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Zəngə qoßul", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Zəngin həcminə görə mikrofon səsi bağlandı", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Zəng bildirißləri", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Zəng dolub", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Qoßul", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Baßla", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Zəng siyahısı doludur", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera sıradan çıxarıldı", @@ -1621,10 +1725,6 @@ "messageformat": "Kameranı aç", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Səsi bağla", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon sıradan çıxarıldı", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Mikrofonu aç", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Paylaß", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Təqdimat sıradan çıxarıldı", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Təqdimatı dayandır", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Zəng", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Qrup, ißtirakçılara zəng etmək ĂŒĂ§ĂŒn çox böyĂŒkdĂŒr.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Zəngi fəallaßdır", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Zəngi qeyri-aktiv et", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Zəng səsini aktivləƟdir", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Daha çox seçim", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Siz", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kameranız bağlıdır", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "GĂŒvənlik nömrəsinə bax", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mesaj", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "GĂŒvənlik nömrəsinə bax", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Telefon nömrəsini alma uğursuz oldu. Bağlantınızı yoxlayıb yenidən sınayın.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Redaktələr yalnız siz bu mesajı göndərdikdən sonra 3 saat ərzində tətbiq oluna bilər.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Redaktələr yalnız siz bu mesajı göndərdikdən sonra 24 saat ərzində tətbiq oluna bilər.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Mesaj silindi.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Qoßma göstərilmək ĂŒĂ§ĂŒn həddən artıq böyĂŒkdĂŒr.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Bəzi qoßmalar göstərilmək ĂŒĂ§ĂŒn həddən artıq böyĂŒkdĂŒr.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "İanə məlumatlarını əldə etmək mĂŒmkĂŒn olmadı", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Yalnız Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Mesajların redaktəsi funksiyası yalnız Signal beta istifadəçiləri ĂŒĂ§ĂŒn əlçatandır. Bir mesajı redaktə etsəniz, onu yalnız Signal betanın son versiyasından istifadə edən Ɵəxslər görə biləcək.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Mesajı redaktə et", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Bir mesajı redaktə etsəniz, onu yalnız Signal-ın son versiyasından istifadə edən Ɵəxslər görə biləcək. Onlar bir mesajı redaktə etdiyinizi görə biləcək.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Gələn görĂŒntĂŒlĂŒ zəng...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Gedən audio zəng", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Gedən görĂŒntĂŒlĂŒ zəng", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} sizə zəng edir", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Yenidən bağlantı qurulur...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} nəfər} other {{count,number} nəfər}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio zəng", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Bitir", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Çıx", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon bağlıdır", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon açıqdır", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zəng aktivdir", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zəng qeyri-aktivdir", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Tənzimləmələr", @@ -3468,13 +3668,25 @@ "messageformat": "Tam ekran zəng", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Tor görĂŒnĂŒĆŸĂŒnə keç", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "GörĂŒnĂŒĆŸĂŒ dəyiß", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Dinamik görĂŒnĂŒĆŸĂŒnə keç", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Tor görĂŒnĂŒĆŸĂŒ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Yan panel görĂŒnĂŒĆŸĂŒ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Reproduktor görĂŒnĂŒĆŸĂŒ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "GörĂŒnĂŒĆŸ yeniləndi", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Zəngi tərk et", @@ -3576,6 +3788,14 @@ "messageformat": "Oldu", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Mesajı redaktə etmək mĂŒmkĂŒn deyil", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Bu mesaj yalnız {max,number} dəfə redaktə edilə bilər.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "TəəssĂŒf ki, sgnl:// bağlantısı anlaßılmazdır!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "İstifadəçi adı", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "İstifadəçi adınızla bağlı xəta yarandı, o artıq hesabınıza təyin edilməyib.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "İstifadəçi adını sil", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "İstifadəçi adı yarat", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kodu və ya keçid", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "İstifadəçi adı sıfırlanmalıdır", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "İstifadəçi adının keçidi sıfırlanmalıdır", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "İstifadəçi adınızı paylaßın", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "İstifadəçi adını sil", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Bu, istifadəçi adınızı siləcək və digər istifadəçilərin onu götĂŒrməsinə icazə verəcək. Əminsiniz?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Bu addım istifadəçi adınızı silib, QR kodunuzu və keçidi qeyri-aktiv edəcək. “{username}” istifadəçi adından baßqaları istifadə edə biləcək. Əminsiniz?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Artıq hekayələri paylaßa və onlara baxa bilməyəcəksiniz. Ən son paylaßdığınız hekayə yeniləmələri də silinəcək.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Dil", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Dil", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistem dili", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Dilləri axtar", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” ĂŒĂ§ĂŒn heç bir nəticə yoxdur", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Tənzimlə", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Tətbiq etmək ĂŒĂ§ĂŒn Signal-ı yenidən baßladın", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Dili dəyißmək ĂŒĂ§ĂŒn tətbiq yenidən baßladılmalıdır.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Yenidən baßlat", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} versiyası mövcuddur", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Tənzimləmələriniz saxlanılarkən xəta baß verdi. Zəhmət olmasa yenidən sınayın.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mesaj", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Əlavə ĂŒslublar", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Sıfırla", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Hazırdır", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "{index,number} / {total,number} istifadəçi adı keçid rəngi", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "QR kodunuzu sıfırlasanız, mövcud QR kodunuz və keçid artıq aktiv olmayacaq.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Keçid sıfırlanır...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kodu və keçid təyin edilməyib. ƞəbəkə bağlantınızı yoxlayıb yenidən cəhd edin.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Signal istifadəçi adınızı təyin edin", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "redaktə edildi", + "messageformat": "DĂŒzəldilib", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Yenidən göndər", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Daha çox əməliyyat", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Zənglər", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Yeni zəng", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Yeni zəng", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Daha çox əməliyyat", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Zəng tarixçəsini təmizlə", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Zəng tarixçəsi təmizlənsin?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Bu əmr bĂŒtĂŒn zəng tarixçəsini daimi olaraq təmizləyəcək", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Təmizlə", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Zəng tarixçəsi təmizləndi", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Baxmaq və ya zəng baßlatmaq ĂŒĂ§ĂŒn klikləyin", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Axtar", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Buraxılmıßlara görə filtrlə", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Aç/bağla", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Yeni zəng yoxdur. Bir dosta zəng edərək baßlayın.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” ĂŒĂ§ĂŒn heç bir nəticə yoxdur", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Gələn zəng", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Gedən zəng", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Cavabsız zəng", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Qrup zəngi", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Yeni söhbət yoxdur.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” ĂŒĂ§ĂŒn heç bir nəticə yoxdur", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Gedən audio zəng} other {Gələn audio zəng}}} Video {{direction, select, Outgoing {Gedən görĂŒntĂŒlĂŒ zəng} other {GörĂŒntĂŒlĂŒ zəng gəlir}}} Group {{direction, select, Outgoing {Gedən qrup zəngi} other {Gələn qrup zəngi}}} other {{direction, select, Outgoing {Gedən zəng} other {Gələn zəng}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Buraxılmıß audio zəng} Video {Cavabsız görĂŒntĂŒlĂŒ zəng} Group {Cavabsız qrup zəngi} other {Cavab verilməmiß zəng}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Cavablanmamıß audio zəng} Video {Cavablanmamıß görĂŒntĂŒlĂŒ zəng} Group {Cavablanmamıß qrup zəngi} other {Cavablanmamıß zəng}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {İmtina edilmiß audio-zəng} Video {İmtina edilmiß video-zəng} Group {İmtina edilmiß qrup zəngi} other {İmtina edilmiß zəng}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {Əlavə {count,number} nəfər də yazır.} other {Əlavə {count,number} nəfər də yazır.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Yeni nə var", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Kiçik spesifik tənzimləmələr, xəta dĂŒzəlißləri və məhsuldarlığın artırılması. Signal istifadə etdiyiniz ĂŒĂ§ĂŒn təƟəkkĂŒrlər!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Bu yeniləmə audio və video zənglər ĂŒĂ§ĂŒn təkmilləƟdirmələr, o cĂŒmlədən sənədlərlə əlaqəli bəzi cĂŒzi yenilikləri əhatə edir. (təƟəkkĂŒrlər, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Artıq Signal-da sistem parametrlərini dəyißmədən də seçilmiß dili dəyiƟə bilərsiniz (Signal Parametrləri > GörĂŒnĂŒĆŸ > Dil)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Bəzi qrup bildirißi piktoqramlarını yenilədik ki, yeni birisi qrupa qoßulduqda xəbəriniz olsun. Bu piktoqramlar oxunaqlılığı təkmilləƟdirməyə kömək edir, xĂŒsusilə də TĂŒnd rəngli temanın qaranlığında yaßayanlar ĂŒĂ§ĂŒn çox faydalıdır. Əvvəlki piktoqramlar sadəcə qaranlıq temaya uyğunlaßdırılmıßdı. Yeni piktoqramlar isə bu qaranlıqdan yaranıb, onun tərəfindən formalaßdırılıb." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Bəzən macOS cihazlarından zəng qrupuna qoßularkən baß verən qısa gecikmələr artıq sizi narahat etməyəcək, bu isə görĂŒĆŸÉ™ yarım saniyə gecikməyin ən azı bir bəhanəsini aradan qaldırmalıdır." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Kimsə qrup zənginə qoßulduqda və ya onu tərk etdikdə video fraqmentləri ilə əlaqəli keçid animasiyasını təkmilləƟdirdik. Dostunuzun ĂŒzĂŒnĂŒn profil görĂŒntĂŒsĂŒnə doğru sĂŒrĂŒĆŸməsi onun sosial hərəkətini bildirir." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Artıq çat baßlığında profil Ɵəklinə və ya qrup avatarına klikləyərək vaxt itirmədən çat parametrlərinə daxil ola və ya həmin çatda nəzərinizdən qaçmıß istənilən hekayəyə baxa bilərsiniz. TəƟəkkĂŒrlər {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/bg-BG/messages.json b/_locales/bg-BG/messages.json index b0d88f888b..d6aea04529 100644 --- a/_locales/bg-BG/messages.json +++ b/_locales/bg-BG/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ĐŸŃ€ĐŸĐ±Đ»Đ”ĐŒ с базата ĐŽĐ°ĐœĐœĐž", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Đ’ŃŠĐ·ĐœĐžĐșĐœĐ° ĐłŃ€Đ”ŃˆĐșа с базата ĐŽĐ°ĐœĐœĐž. ĐœĐŸĐ¶Đ”Ń‚Đ” Ўа ĐșĐŸĐżĐžŃ€Đ°Ń‚Đ” ĐłŃ€Đ”ŃˆĐșата Đž Ўа сД сĐČържДтД с ĐżĐŸĐŽĐŽŃ€ŃŠĐ¶Đșата ĐœĐ° Signal, за Ўа ĐČĐž ĐżĐŸĐŒĐŸĐłĐœĐ°Ń‚ с ĐŸŃ‚ŃŃ‚Ń€Đ°ĐœŃĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° ĐżŃ€ĐŸĐ±Đ»Đ”ĐŒĐ°. АĐșĐŸ сД ĐœĐ°Đ»Đ°ĐłĐ° Ўа ĐžĐ·ĐżĐŸĐ»Đ·ĐČатД Signal ĐČĐ”ĐŽĐœĐ°ĐłĐ°, ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ОзтрОДтД ĐŽĐ°ĐœĐœĐžŃ‚Đ” сО Đž Ўа рДстартОратД.\n\nĐĄĐČържДтД сД с ĐżĐŸĐŽĐŽŃ€ŃŠĐ¶Đșата, ĐșĐ°Ń‚ĐŸ ĐżĐŸŃĐ”Ń‚ĐžŃ‚Đ”: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° ĐČсочĐșĐž ĐŽĐ°ĐœĐœĐž Đž рДстарт", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° ĐŽĐ°ĐœĐœĐž Đž Ń€Đ”ŃŃ‚Đ°Ń€Ń‚ĐžŃ€Đ°ĐœĐ”", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ĐŸĐ”Ń€ĐŒĐ°ĐœĐ”ĐœŃ‚ĐœĐŸ ОзтрОĐČĐ°ĐœĐ” ĐœĐ° ĐČсочĐșĐž ĐŽĐ°ĐœĐœĐž?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ° ĐœĐ° ĐČсочĐșĐž ĐČашО ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ Đž ĐŒŃƒĐ»Ń‚ĐžĐŒĐ”ĐŽĐžŃŃ‚Đ° ĐČĐž щД бъЎат ĐżĐ”Ń€ĐŒĐ°ĐœĐ”ĐœŃ‚ĐœĐŸ ОзтрОтО ĐŸŃ‚ Ń‚ĐŸĐČа ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸ. ЩД ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐžĐ·ĐżĐŸĐ»Đ·ĐČатД Signal ĐœĐ° Ń‚ĐŸĐČа ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸ, слДЎ ĐșĐ°Ń‚ĐŸ ĐłĐŸ сĐČържДтД ĐŸŃ‚ĐœĐŸĐČĐŸ. ĐąĐŸĐČа ĐœŃĐŒĐ° Ўа ОзтрОД ĐœĐžĐșаĐșĐČĐž ĐŽĐ°ĐœĐœĐž ĐŸŃ‚ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ° ĐČĐž.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Đ’Đ”Ń€ŃĐžŃŃ‚Đ° ĐœĐ° ĐČашата база ĐŽĐ°ĐœĐœĐž ĐœĐ” ŃŃŠĐŸŃ‚ĐČДтстĐČа ĐœĐ° тазО ĐČĐ”Ń€ŃĐžŃ ĐœĐ° Signal. ĐŁĐČДрДтД сД, чД ĐŸŃ‚ĐČĐ°Ń€ŃŃ‚Đ” ĐœĐ°Đč-ĐœĐŸĐČата ĐČĐ”Ń€ŃĐžŃ ĐœĐ° Signal ĐœĐ° ĐșĐŸĐŒĐżŃŽŃ‚ŃŠŃ€Đ° сО.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ЀаĐčĐ»", @@ -300,6 +316,70 @@ "messageformat": "Đ§Đ°Ń‚ĐŸĐČĐ”", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ĐĐ”Ń‰ĐŸ сД ĐŸĐ±ŃŠŃ€Đșа с ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ”, Ń‚ĐŸ ĐČДчД ĐœĐ” Đ” сĐČŃŠŃ€Đ·Đ°ĐœĐŸ с аĐșĐ°ŃƒĐœŃ‚Đ° ĐČĐž. ĐœĐŸĐ¶Đ”Ń‚Đ” Ўа ĐŸĐżĐžŃ‚Đ°Ń‚Đ” Ўа ĐłĐŸ заЎаЎДтД ĐŸŃ‚ĐœĐŸĐČĐŸ ОлО Ўа сО ОзбДрДтД ĐŽŃ€ŃƒĐłĐŸ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ĐšĐŸŃ€ĐžĐłĐžŃ€Đ°ĐœĐ” сДга", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ĐĐ”Ń‰ĐŸ сД ĐŸĐ±ŃŠŃ€Đșа с QR ĐșĐŸĐŽĐ° Đž Đ»ĐžĐœĐșа с ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸŃ‚ĐŸ ĐČĐž ĐžĐŒĐ”, тД ĐČДчД ĐœĐ” са ĐČĐ°Đ»ĐžĐŽĐœĐž. НапраĐČДтД ĐœĐŸĐČ Đ»ĐžĐœĐș, за Ўа ĐłĐŸ ŃĐżĐŸĐŽĐ”Đ»ŃŃ‚Đ” със ĐŽŃ€ŃƒĐłĐžŃ‚Đ”.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ĐšĐŸŃ€ĐžĐłĐžŃ€Đ°ĐœĐ” сДга", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ĐŸĐŸĐșазĐČĐ°ĐœĐ” ĐœĐ° разЎДлО", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ĐĄĐșроĐČĐ°ĐœĐ” ĐœĐ° разЎДлО", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Đ’ŃŠĐ·ĐœĐžĐșĐœĐ° ĐłŃ€Đ”ŃˆĐșа", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ĐœĐ”ĐżŃ€ĐŸŃ‡Đ”Ń‚Đ”ĐœĐž", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "МарĐșĐžŃ€Đ°ĐœĐ” ĐșĐ°Ń‚ĐŸ ĐœĐ”ĐżŃ€ĐŸŃ‡Đ”Ń‚Đ”ĐœĐž", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Đ§Đ°Ń‚ĐŸĐČĐ”", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ĐžĐ±Đ°Đ¶ĐŽĐ°ĐœĐžŃ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžĐž", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ĐžĐ±ĐœĐŸĐČяĐČĐ°ĐœĐ” ĐœĐ° Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„ĐžĐ»", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ĐžĐ±Ń€Đ°Ń‚ĐœĐŸ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "йДзО Ń‡Đ°Ń‚ĐŸĐČĐ” са архоĐČĐžŃ€Đ°ĐœĐž Đž щД сД ĐżĐŸĐșазĐČат ĐČъĐČ Đ’Ń…ĐŸĐŽŃŃ‰Đ°Ń‚Đ° Đșутоя ŃĐ°ĐŒĐŸ аĐșĐŸ бъЎат ĐżĐŸĐ»ŃƒŃ‡Đ”ĐœĐž ĐœĐŸĐČĐž ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ОбаЎО сД ĐČсД паĐș", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ВĐșлючĐČĐ°ĐœĐ” ĐČъпрДĐșĐž Ń‚ĐŸĐČа", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ĐŸŃ€ĐŸĐŽŃŠĐ»Đ¶Đž ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”Ń‚ĐŸ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ĐĐŸĐŒĐ”Ń€Đ°Ń‚Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚ сД аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·ĐžŃ€Đ°Ń‚.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ĐĐ°ŃƒŃ‡Đ”Ń‚Đ” ĐżĐŸĐČДчД", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐŸŃ€Đ”ĐŽĐžŃˆĐ”Đœ ĐœĐŸĐŒĐ”Ń€ за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ХлДЎĐČащ ĐœĐŸĐŒĐ”Ń€ за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Đ’Đ”Ń€ŃĐžŃ ĐœĐ° ĐœĐŸĐŒĐ”Ń€Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚, {index,number} ĐŸŃ‚ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "МарĐșораĐčтД ĐșĐ°Ń‚ĐŸ ĐżĐŸŃ‚ĐČŃŠŃ€ĐŽĐ”Đœ", @@ -663,33 +747,41 @@ "messageformat": "Đ˜Đ·Ń‡ĐžŃŃ‚ĐČĐ°ĐœĐ” ĐœĐ° ĐżĐŸŃ‚ĐČŃŠŃ€Đ¶ĐŽĐ”ĐœĐžĐ”", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "За Ўа ĐżŃ€ĐŸĐČДрОтД ĐșŃ€ĐžĐżŃ‚ĐžŃ€Đ°ĐœĐ”Ń‚ĐŸ ĐŸŃ‚ ĐșраĐč ĐŽĐŸ ĐșраĐč ĐŒĐ”Đ¶ĐŽŃƒ ĐČас Đž {name}, сраĐČĐœĐ”Ń‚Đ” цОфрОтД ĐżĐŸ-ĐłĐŸŃ€Đ” с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ ĐœĐ° Юругоя ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ». ĐžŃ‚ŃŃ€Đ”Ń‰ĐœĐ°Ń‚Đ° ŃŃ‚Ń€Đ°ĐœĐ° ŃŃŠŃ‰ĐŸ ĐŒĐŸĐ¶Đ” Ўа сĐșĐ°ĐœĐžŃ€Đ° ĐșĐŸĐŽĐ° с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ сО.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ĐĐ°ŃƒŃ‡Đ”Ń‚Đ” ĐżĐŸĐČДчД", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "За Ўа ĐżŃ€ĐŸĐČДрОтД ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚Ń‚Đ° ĐœĐ° ĐșŃ€ĐžĐżŃ‚ĐžŃ€Đ°ĐœĐ”Ń‚ĐŸ ĐŸŃ‚ ĐșраĐč ĐŽĐŸ ĐșраĐč ĐŒĐ”Đ¶ĐŽŃƒ ĐČас Đž {name}, ĐœĐ°ĐżĐ°ŃĐœĐ”Ń‚Đ” цĐČĐ”Ń‚ĐœĐ°Ń‚Đ° Đșарта ĐżĐŸ-ĐłĐŸŃ€Đ” с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ ĐœĐ° Юругоя ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ» Đž сраĐČĐœĐ”Ń‚Đ” цОфрОтД. АĐșĐŸ ĐœĐ” съĐČпаЮат, ĐżŃ€ĐŸĐ±ĐČаĐčтД Юругата ĐŽĐČĐŸĐčĐșа ĐœĐŸĐŒĐ”Ń€Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚. Đ”ĐŸŃŃ‚Đ°Ń‚ŃŠŃ‡ĐœĐŸ Đ” Đ”ĐŽĐœĐ° ĐŽĐČĐŸĐčĐșа Ўа съĐČĐżĐ°ĐŽĐœĐ”.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "За Ўа ĐżŃ€ĐŸĐČДрОтД ĐșŃ€ĐžĐżŃ‚ĐžŃ€Đ°ĐœĐ”Ń‚ĐŸ ĐŸŃ‚ ĐșраĐč ĐŽĐŸ ĐșраĐč ĐŒĐ”Đ¶ĐŽŃƒ ĐČас Đž {name}, сраĐČĐœĐ”Ń‚Đ” цОфрОтД ĐżĐŸ-ĐłĐŸŃ€Đ” с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ ĐœĐ° Юругоя ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ». ĐžŃ‚ŃŃ€Đ”Ń‰ĐœĐ°Ń‚Đ° ŃŃ‚Ń€Đ°ĐœĐ° ŃŃŠŃ‰ĐŸ ĐŒĐŸĐ¶Đ” Ўа сĐșĐ°ĐœĐžŃ€Đ° ĐșĐŸĐŽĐ° с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ сО.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ĐŸŃ€ĐŸĐŒĐ”ĐœĐž ĐČ ĐœĐŸĐŒĐ”Ń€Đ°Ń‚Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ĐĐŸĐŒĐ”Ń€Đ°Ń‚Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚ сД аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·ĐžŃ€Đ°Ń‚ прДз ĐżŃ€Đ”Ń…ĐŸĐŽĐ”Đœ ĐżĐ”Ń€ĐžĐŸĐŽ, за Ўа сД аĐșтоĐČорат ĐżŃ€Đ”ĐŽŃŃ‚ĐŸŃŃ‰ĐžŃ‚Đ” Ń„ŃƒĐœĐșцоо за ĐżĐŸĐČĐ”Ń€ĐžŃ‚Đ”Đ»ĐœĐŸŃŃ‚ ĐČ Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "За Ўа ĐżĐŸŃ‚ĐČърЎОтД ĐœĐŸĐŒĐ”Ń€Đ°Ń‚Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚, цĐČĐ”Ń‚ĐœĐ°Ń‚Đ° Đșарта Ń‚Ń€ŃĐ±ĐČа Ўа съĐČĐżĐ°ĐŽĐœĐ” с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ ĐœĐ° ĐČашоя ĐșĐŸĐœŃ‚Đ°Đșт. АĐșĐŸ ĐœĐ” съĐČпаЮат, ĐżŃ€ĐŸĐ±ĐČаĐčтД Юругата ĐŽĐČĐŸĐčĐșа ĐœĐŸĐŒĐ”Ń€Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚. Đ”ĐŸŃŃ‚Đ°Ń‚ŃŠŃ‡ĐœĐŸ Đ” Đ”ĐŽĐœĐ° ĐŽĐČĐŸĐčĐșа Ўа съĐČĐżĐ°ĐŽĐœĐ”.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ĐŃƒĐ¶ĐŽĐ° ĐŸŃ‚ ĐżĐŸĐŒĐŸŃ‰?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ĐŻŃĐœĐŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ЩД бъЎД ŃŃŠĐ·ĐŽĐ°ĐŽĐ”Đœ ĐœĐŸĐŒĐ”Ń€ за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚ с Ń‚ĐŸĐ·Đž Ń‡ĐŸĐČĐ”Đș, слДЎ ĐșĐ°Ń‚ĐŸ Ń€Đ°Đ·ĐŒĐ”ĐœĐžŃ‚Đ” ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ с ĐœĐ”ĐłĐŸ.", @@ -1267,10 +1359,6 @@ "messageformat": "РазглДЎаĐč ĐżĐŸŃĐ»Đ”ĐŽĐœĐ°Ń‚Đ° ĐŒŃƒĐ»Ń‚ĐžĐŒĐ”ĐŽĐžŃ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "За Ўа ĐżŃ€ĐŸĐČДрОтД ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚Ń‚Đ° ĐœĐ° ĐșŃ€ĐžĐżŃ‚ĐžŃ€Đ°ĐœĐ”Ń‚ĐŸ ĐŸŃ‚ ĐșраĐč ĐŽĐŸ ĐșраĐč ĐŒĐ”Đ¶ĐŽŃƒ ĐČас Đž {name}, сраĐČĐœĐ”Ń‚Đ” цОфрОтД ĐżĐŸ-ĐłĐŸŃ€Đ” с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸŃ‚ĐŸ ĐœĐ° Юругоя ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ». ĐžŃ‚ŃŃ€Đ”Ń‰ĐœĐ°Ń‚Đ° ŃŃ‚Ń€Đ°ĐœĐ° ŃŃŠŃ‰ĐŸ ĐŒĐŸĐ¶Đ” Ўа сĐșĐ°ĐœĐžŃ€Đ° QR ĐșĐŸĐŽĐ° ĐżĐŸ-ĐłĐŸŃ€Đ”.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ВсД ĐŸŃ‰Đ” ĐœĐ” стД сД ĐŸĐ±ĐŒĐ”ĐœŃĐ»Đž ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ с Ń‚ĐŸĐ·Đž ĐșĐŸĐœŃ‚Đ°Đșт. Вашоят ĐœĐŸĐŒĐ”Ń€ за Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚ с ĐœĐ”ĐłĐŸ щД бъЎД ĐœĐ° Ń€Đ°Đ·ĐżĐŸĐ»ĐŸĐ¶Đ”ĐœĐžĐ” слДЎ пърĐČĐŸŃ‚ĐŸ ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”." }, @@ -1334,17 +1422,17 @@ "messageformat": "Đ˜ĐœŃ„ĐŸŃ€ĐŒĐ°Ń†ĐžŃ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ”", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃŃ‚Đ°", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° чата?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃŃ‚Đ°?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Чатът щД бъЎД ОзтрОт ĐŸŃ‚ Ń‚ĐŸĐČа ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸ.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ĐĄŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃŃ‚Đ° ĐČ Ń‚ĐŸĐ·Đž чат щД бъЎат ОзтрОтО ĐŸŃ‚ Ń‚ĐŸĐČа ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸ. ПаĐș щД ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа търсОтД Ń‚ĐŸĐ·Đž чат, слДЎ ĐșĐ°Ń‚ĐŸ ОзтрОДтД ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃŃ‚Đ°.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "НапусĐșĐ°ĐœĐ” ĐœĐ° групата", @@ -1438,6 +1526,14 @@ "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ° ĐœĐ° ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃŃ‚Đ° ĐČĐž за ĐŽĐČата чата Đ” ĐŸĐ±Đ”ĐŽĐžĐœĐ”ĐœĐ° туĐș.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} ĐżŃ€ĐžĐœĐ°ĐŽĐ»Đ”Đ¶Đž ĐœĐ° {conversationTitle}. И ĐŽĐČĐ°ĐŒĐ°Ń‚Đ° стД Ń‡Đ»Đ”ĐœĐŸĐČĐ” ĐœĐ° {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} ĐżŃ€ĐžĐœĐ°ĐŽĐ»Đ”Đ¶Đž ĐœĐ° {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽ ĐœĐ° ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ” ĐŸŃ‚ Ń†ĐžŃ‚ĐžŃ€Đ°ĐœĐŸ ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ĐŸĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Đ—Đ°ĐżĐŸŃ‡ĐœĐž Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ĐŸŃ€ĐžŃŃŠĐ”ĐŽĐž сД ĐșŃŠĐŒ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœŃŠŃ‚ Đ” Đ·Đ°ĐłĐ»ŃƒŃˆĐ”Đœ ĐżĐŸŃ€Đ°ĐŽĐž Ń€Đ°Đ·ĐŒĐ”Ń€Đ° ĐœĐ° ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”Ń‚ĐŸ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ИзĐČĐ”ŃŃ‚ĐžŃ за Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ĐŸĐŸĐČĐžĐșĐČĐ°ĐœĐ”Ń‚ĐŸ Đ” ĐżŃŠĐ»ĐœĐŸ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ĐŸŃ€ĐžŃŃŠĐ”ĐŽĐžĐœĐž сД", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ĐĐ°Ń‡Đ°Đ»ĐŸ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ĐŸĐŸĐČĐžĐșĐČĐ°ĐœĐ”Ń‚ĐŸ Đ” ĐżŃŠĐ»ĐœĐŸ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°Ń‚Đ° Đ” ЎДаĐșтоĐČĐžŃ€Đ°ĐœĐ°", @@ -1621,10 +1725,6 @@ "messageformat": "ВĐșлючО ĐșĐ°ĐŒĐ”Ń€Đ°Ń‚Đ°", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Đ—Đ°ĐłĐ»ŃƒŃˆĐ°ĐČĐ°ĐœĐ”", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœŃŠŃ‚ Đ” ЎДаĐșтоĐČĐžŃ€Đ°Đœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐœĐž заглушаĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœĐ°", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ĐĄĐżĐŸĐŽĐ”Đ»ŃĐœĐ”", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ĐŸŃ€Đ”Đ·Đ”ĐœŃ‚ĐžŃ€Đ°ĐœĐ”Ń‚ĐŸ Đ” ЎДаĐșтоĐČĐžŃ€Đ°ĐœĐŸ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Спро ĐżŃ€Đ”Đ·Đ”ĐœŃ‚ĐžŃ€Đ°ĐœĐ”", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ЗĐČŃŠĐœĐœĐž", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Групата Đ” тĐČърЎД ĐłĐŸĐ»ŃĐŒĐ°, за Ўа Đ·ĐČŃŠĐœĐœĐ”Ń‚Đ” ĐœĐ° просъстĐČащОтД.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "АĐșтоĐČĐžŃ€Đ°ĐœĐ” ĐœĐ° Đ·ĐČŃŠĐœĐ”ĐœĐ”Ń‚ĐŸ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ИзĐșлючĐČĐ°ĐœĐ” ĐœĐ° Đ·ĐČŃŠĐœĐ”ĐœĐ”Ń‚ĐŸ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ВĐșлючĐČĐ°ĐœĐ” ĐœĐ° Đ·ĐČŃŠĐœĐ”ĐœĐ”Ń‚ĐŸ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ОщД ĐŸĐżŃ†ĐžĐž", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ВОД", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°Ń‚Đ° Đ” ОзĐșĐ»ŃŽŃ‡Đ”ĐœĐ°", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ВОжтД ĐœĐŸĐŒĐ”Ń€Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ĐĄŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ВОжтД ĐœĐŸĐŒĐ”Ń€Đ° за ŃĐžĐłŃƒŃ€ĐœĐŸŃŃ‚", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ĐĐ”ŃƒŃĐżĐ”ŃˆĐœĐŸ ОзĐČĐ»ĐžŃ‡Đ°ĐœĐ” ĐœĐ° Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ”Đœ ĐœĐŸĐŒĐ”Ń€. ĐŸŃ€ĐŸĐČДрДтД ĐČръзĐșата сО Đž ĐŸĐżĐžŃ‚Đ°ĐčтД ĐŸŃ‚ĐœĐŸĐČĐŸ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "РДЎаĐșцООтД ĐŒĐŸĐłĐ°Ń‚ Ўа сД прОлагат ŃĐ°ĐŒĐŸ ĐČ Ń€Đ°ĐŒĐșОтД ĐœĐ° 3 часа ĐŸŃ‚ ĐŒĐŸĐŒĐ”ĐœŃ‚Đ° ĐœĐ° ĐžĐ·ĐżŃ€Đ°Ń‰Đ°ĐœĐ” ĐœĐ° Ń‚ĐŸĐČа ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "РДЎаĐșцООтД ĐŒĐŸĐłĐ°Ń‚ Ўа сД прОлагат ŃĐ°ĐŒĐŸ ĐČ Ń€Đ°ĐŒĐșОтД ĐœĐ° 24 часа ĐŸŃ‚ ĐŒĐŸĐŒĐ”ĐœŃ‚Đ° ĐœĐ° ĐžĐ·ĐżŃ€Đ°Ń‰Đ°ĐœĐ” ĐœĐ° Ń‚ĐŸĐČа ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ĐąĐŸĐČа ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ” бДшД ĐžĐ·Ń‚Ń€ĐžŃ‚ĐŸ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ПроĐșĐ°Ń‡Đ”ĐœĐžŃŃ‚ фаĐčĐ» Đ” прДĐșĐ°Đ»Đ”ĐœĐŸ ĐłĐŸĐ»ŃĐŒ за ĐżĐŸĐșазĐČĐ°ĐœĐ”.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "НяĐșĐŸĐž проĐșĐ°Ń‡Đ”ĐœĐž фаĐčĐ»ĐŸĐČĐ” са прДĐșĐ°Đ»Đ”ĐœĐŸ ĐłĐŸĐ»Đ”ĐŒĐž за ĐżĐŸĐșазĐČĐ°ĐœĐ”.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ĐĐ”ŃƒŃĐżĐ”ŃˆĐœĐŸ ОзĐČĐ»ĐžŃ‡Đ°ĐœĐ” ĐœĐ° ĐŽĐ°ĐœĐœĐž за ĐŽĐ°Ń€Đ”ĐœĐžĐ”", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ĐĄĐ°ĐŒĐŸ за Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "РДЎаĐșŃ‚ĐžŃ€Đ°ĐœĐ”Ń‚ĐŸ ĐœĐ° ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ Đ” ĐŽĐŸŃŃ‚ŃŠĐżĐœĐŸ ŃĐ°ĐŒĐŸ за бДта ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»Đž ĐœĐ° Signal. АĐșĐŸ рДЎаĐșтОратД ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”, Ń‚ĐŸ щД сД ĐČОжЎа ŃĐ°ĐŒĐŸ ĐŸŃ‚ Ń…ĐŸŃ€Đ°, ĐșĐŸĐžŃ‚ĐŸ ĐžĐ·ĐżĐŸĐ»Đ·ĐČат ĐœĐ°Đč-ĐœĐŸĐČата ĐČĐ”Ń€ŃĐžŃ ĐœĐ° Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "РДЎаĐșŃ‚ĐžŃ€Đ°ĐœĐ” ĐœĐ° ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "АĐșĐŸ рДЎаĐșтОратД ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”, Ń‚ĐŸ щД сД ĐČОжЎа ŃĐ°ĐŒĐŸ ĐŸŃ‚ Ń…ĐŸŃ€Đ°, ĐșĐŸĐžŃ‚ĐŸ ĐžĐ·ĐżĐŸĐ»Đ·ĐČат ĐœĐ°Đč-ĐœĐŸĐČОтД ĐČДрсОО ĐœĐ° Signal. йД щД ĐČОжЎат, чД стД рДЎаĐșтОралО ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”Ń‚ĐŸ.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Đ’Ń…ĐŸĐŽŃŃ‰ĐŸ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ ĐłĐ»Đ°ŃĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ĐČĐž Đ·ĐČŃŠĐœĐž", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ĐŸĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ сĐČързĐČĐ°ĐœĐ”â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} Ń‡ĐŸĐČĐ”Đș} other {{count,number} ЎушО}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ĐŃƒĐŽĐžĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ЗатĐČĐŸŃ€Đž", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ĐĐ°ĐżŃƒŃĐœĐž", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœŃŠŃ‚ Đ” ОзĐșĐ»ŃŽŃ‡Đ”Đœ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœŃŠŃ‚ Đ” ĐČĐșĐ»ŃŽŃ‡Đ”Đœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ЗĐČŃŠĐœĐ”ĐœĐ”Ń‚ĐŸ Đ” ĐČĐșĐ»ŃŽŃ‡Đ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ЗĐČŃŠĐœĐ”ĐœĐ”Ń‚ĐŸ Đ” ОзĐșĐ»ŃŽŃ‡Đ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž", @@ -3468,13 +3668,25 @@ "messageformat": "Đ Đ°Đ·ĐłĐŸĐČĐŸŃ€ ĐœĐ° Ń†ŃĐ» Đ”ĐșŃ€Đ°Đœ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐŸŃ€Đ”ĐČĐșлючĐČĐ°ĐœĐ” ĐșŃŠĐŒ ОзглДЎ ĐČ Ń€Đ”ŃˆĐ”Ń‚Đșа", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ĐŸŃ€ĐŸĐŒŃĐœĐ° ĐœĐ° ОзглДЎа", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ĐŸŃ€Đ”ĐČĐșлючĐČĐ°ĐœĐ” ĐșŃŠĐŒ ОзглДЎ за ĐłĐŸĐČĐŸŃ€ĐžŃ‚Đ”Đ»", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ИзглДЎ с Ń€Đ”ŃˆĐ”Ń‚Đșа", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ИзглДЎ със ŃŃ‚Ń€Đ°ĐœĐžŃ‡ĐœĐ° Đ»Đ”ĐœŃ‚Đ°", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ИзглДЎ с ĐłĐŸĐČĐŸŃ€ĐžŃ‚Đ”Đ»", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Đ˜Đ·ĐłĐ»Đ”ĐŽŃŠŃ‚ Đ” аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·ĐžŃ€Đ°Đœ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ĐĐ°ĐżŃƒŃĐœĐž ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”Ń‚ĐŸ", @@ -3576,6 +3788,14 @@ "messageformat": "Đ”ĐŸĐ±Ń€Đ”", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ĐĄŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”Ń‚ĐŸ ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД рДЎаĐșŃ‚ĐžŃ€Đ°ĐœĐŸ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ĐŸĐŸ Ń‚ĐŸĐČа ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ” ĐŒĐŸĐłĐ°Ń‚ Ўа сД ОзĐČършат ŃĐ°ĐŒĐŸ {max,number} рДЎаĐșцоо.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ĐĄŃŠĐ¶Đ°Đ»ŃĐČĐ°ĐŒĐ”, Ń‚ĐŸĐ·Đž Đ»ĐžĐœĐș със sgnl:// ĐœĐ” Đ·ĐœĐ°Ń‡Đ”ŃˆĐ” ĐœĐžŃ‰ĐŸ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ĐŸĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ”", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ĐĐ”Ń‰ĐŸ сД ĐŸĐ±ŃŠŃ€Đșа с ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ”, Ń‚ĐŸ ĐČДчД ĐœĐ” Đ” сĐČŃŠŃ€Đ·Đ°ĐœĐŸ с аĐșĐ°ŃƒĐœŃ‚Đ° ĐČĐž.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ”", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ХъзЎаĐČĐ°ĐœĐ” ĐœĐ° ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ”", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ĐșĐŸĐŽ ОлО Đ»ĐžĐœĐș", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ĐŸĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸŃ‚ĐŸ ĐžĐŒĐ” Ń‚Ń€ŃĐ±ĐČа Ўа сД ĐœŃƒĐ»ĐžŃ€Đ°", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Đ›ĐžĐœĐșът за ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ” Ń‚Ń€ŃĐ±ĐČа Ўа сД ĐœŃƒĐ»ĐžŃ€Đ°", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ĐĄĐżĐŸĐŽĐ”Đ»Đ”Ń‚Đ” ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸŃ‚ĐŸ сО ĐžĐŒĐ”", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Đ˜Đ·Ń‚Ń€ĐžĐČĐ°ĐœĐ” ĐœĐ° ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ”", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ĐąĐŸĐČа щД ĐżŃ€Đ”ĐŒĐ°Ń…ĐœĐ” ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸŃ‚ĐŸ ĐČĐž ĐžĐŒĐ” Đž щД ĐżĐŸĐ·ĐČĐŸĐ»Đž ĐœĐ° Юруго ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»Đž Ўа ĐłĐŸ ĐČĐ·Đ”ĐŒĐ°Ń‚. ĐĄĐžĐłŃƒŃ€ĐœĐž лО стД?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ĐąĐŸĐČа щД ĐżŃ€Đ”ĐŒĐ°Ń…ĐœĐ” ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸ ĐžĐŒĐ” Đž щД ЎДаĐșтоĐČора ĐČашоя QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș. „{username}“ щД бъЎД ĐŽĐŸŃŃ‚ŃŠĐżĐ”Đœ за Đ·Đ°ŃĐČяĐČĐ°ĐœĐ” ĐŸŃ‚ Юруго. ĐĄĐžĐłŃƒŃ€ĐœĐž лО стД?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ĐŸĐŸĐČДчД ĐœŃĐŒĐ° Ўа ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ŃĐżĐŸĐŽĐ”Đ»ŃŃ‚Đ” ОлО глДЎатД ĐžŃŃ‚ĐŸŃ€ĐžĐž. АĐșŃ‚ŃƒĐ°Đ»ĐžĐ·Đ°Ń†ĐžĐžŃ‚Đ” ĐœĐ° ĐžŃŃ‚ĐŸŃ€ĐžĐž, ĐșĐŸĐžŃ‚ĐŸ стД ŃĐżĐŸĐŽĐ”Đ»ĐžĐ»Đž ĐœĐ°ŃĐșĐŸŃ€ĐŸ, ŃŃŠŃ‰ĐŸ щД бъЎат ОзтрОтО.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ЕзОĐș", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ЕзОĐș", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ЕзОĐș ĐœĐ° ŃĐžŃŃ‚Đ”ĐŒĐ°Ń‚Đ°", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ĐąŃŠŃ€ŃĐ”ĐœĐ” ĐœĐ° ДзОцО", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ĐĐ” са ĐŸŃ‚Đșрото Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đž за „{searchTerm}“", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ЗаЮаĐČĐ°ĐœĐ”", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "РДстартОраĐčтД Signal за ĐżŃ€ĐžĐ»Đ°ĐłĐ°ĐœĐ”", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "За Ўа ĐżŃ€ĐŸĐŒĐ”ĐœĐžŃ‚Đ” ДзОĐșа, ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐ”Ń‚ĐŸ Ń‚Ń€ŃĐ±ĐČа Ўа сД рДстартОра.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Đ Đ”ŃŃ‚Đ°Ń€Ń‚ĐžŃ€Đ°ĐœĐ”", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ĐĐ°Đ»ĐžŃ‡ĐœĐ° Đ” аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·Đ°Ń†ĐžŃ ĐŽĐŸ ĐČĐ”Ń€ŃĐžŃ {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Đ’ŃŠĐ·ĐœĐžĐșĐœĐ° ĐłŃ€Đ”ŃˆĐșа про запазĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșОтД ĐČĐž. ĐœĐŸĐ»Ń, ĐŸĐżĐžŃ‚Đ°ĐčтД ĐŸŃ‚ĐœĐŸĐČĐŸ.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ĐĄŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ОщД ŃŃ‚ĐžĐ»ĐŸĐČĐ”", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "РДстартОраĐč", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Đ“ĐŸŃ‚ĐŸĐČĐŸ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ĐŠĐČят ĐœĐ° ĐČръзĐșата ĐșŃŠĐŒ ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸŃ‚ĐŸ ĐžĐŒĐ”, {index,number} ĐŸŃ‚ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "АĐșĐŸ ĐœŃƒĐ»ĐžŃ€Đ°Ń‚Đ” сĐČĐŸŃ QR ĐșĐŸĐŽ, ĐČашоят същДстĐČуĐČащ QR ĐșĐŸĐŽ Đž ĐČръзĐșа ĐČДчД ĐœŃĐŒĐ° Ўа Ń€Đ°Đ±ĐŸŃ‚ŃŃ‚.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ĐŃƒĐ»ĐžŃ€Đ°ĐœĐ” ĐœĐ° Đ»ĐžĐœĐșа
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "ĐĐ” са Đ·Đ°ĐŽĐ°ĐŽĐ”ĐœĐž QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș. ĐŸŃ€ĐŸĐČДрДтД ĐŒŃ€Đ”Đ¶ĐŸĐČата сО ĐČръзĐșа Đž ĐŸĐżĐžŃ‚Đ°ĐčтД ĐŸŃ‚ĐœĐŸĐČĐŸ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ЗаЮаĐčтД ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃĐșĐŸŃ‚ĐŸ сО ĐžĐŒĐ” за Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "рДЎаĐșŃ‚ĐžŃ€Đ°ĐœĐŸ", + "messageformat": "РДЎаĐșŃ‚ĐžŃ€Đ°ĐœĐŸ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ĐŸĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ Đ˜Đ·ĐżŃ€Đ°Ń‰Đ°ĐœĐ”", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ĐŸĐŸĐČДчД ĐŸĐżŃ†ĐžĐž", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ĐžĐ±Đ°Đ¶ĐŽĐ°ĐœĐžŃ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ĐĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ĐĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ĐŸĐŸĐČДчД ĐŸĐżŃ†ĐžĐž", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Đ˜Đ·Ń‡ĐžŃŃ‚ĐČĐ°ĐœĐ” ĐœĐ° ĐžŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ° ĐœĐ° ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐžŃŃ‚Đ°", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Đ˜Đ·Ń‡ĐžŃŃ‚ĐČĐ°ĐœĐ” ĐœĐ° ĐžŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ° ĐœĐ° ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐžŃŃ‚Đ°?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ĐąĐŸĐČа ĐżĐ”Ń€ĐŒĐ°ĐœĐ”ĐœŃ‚ĐœĐŸ щД ОзтрОД Ń†ŃĐ»Đ°Ń‚Đ° ĐžŃŃ‚ĐŸŃ€ĐžŃ ĐœĐ° ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐžŃŃ‚Đ°", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Đ˜Đ·Ń‡ĐžŃŃ‚ĐČĐ°ĐœĐ”", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ° ĐœĐ° ĐžĐ±Đ°Đ¶ĐŽĐ°ĐœĐžŃŃ‚Đ° Đ” Đ˜Đ·Ń‡ĐžŃŃ‚Đ”ĐœĐ°", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "КлОĐșĐœĐ”Ń‚Đ”, за Ўа ĐČОЎОтД ОлО Đ·Đ°ĐżĐŸŃ‡ĐœĐ”Ń‚Đ” ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ĐąŃŠŃ€ŃĐ”ĐœĐ”", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Đ€ĐžĐ»Ń‚Ń€ĐžŃ€Đ°ĐœĐ” ĐżĐŸ ĐżŃ€ĐŸĐżŃƒŃĐœĐ°Ń‚Đž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ĐŸŃ€Đ”ĐČĐșлючĐČĐ°ĐœĐ”", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĐŃĐŒĐ° сĐșĐŸŃ€ĐŸŃˆĐœĐž ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐžŃ. Đ—Đ°ĐżĐŸŃ‡ĐœĐ”Ń‚Đ”, ĐșĐ°Ń‚ĐŸ сД ĐŸĐ±Đ°ĐŽĐžŃ‚Đ” ĐœĐ° ĐżŃ€ĐžŃŃ‚Đ”Đ».", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ĐĐ” са ĐŸŃ‚Đșрото Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đž за „{query}“", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Đ’Ń…ĐŸĐŽŃŃ‰Đž", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ĐŸŃ€ĐŸĐżŃƒŃĐœĐ°Ń‚ĐŸ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Đ“Ń€ŃƒĐżĐŸĐČ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĐŃĐŒĐ° сĐșĐŸŃ€ĐŸŃˆĐœĐž Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ĐĐ” са ĐŸŃ‚Đșрото Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đž за „{query}“", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ ĐłĐ»Đ°ŃĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐŸ ĐłĐ»Đ°ŃĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”}}} Video {{direction, select, Outgoing {Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐŸ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”}}} Group {{direction, select, Outgoing {Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ ĐłŃ€ŃƒĐżĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐŸ ĐłŃ€ŃƒĐżĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”}}} other {{direction, select, Outgoing {Đ˜Đ·Ń…ĐŸĐŽŃŃ‰ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ĐŸŃ€ĐŸĐżŃƒŃĐœĐ°Ń‚ĐŸ ĐłĐ»Đ°ŃĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} Video {ĐŸŃ€ĐŸĐżŃƒŃĐœĐ°Ń‚ĐŸ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} Group {ĐŸŃ€ĐŸĐżŃƒŃĐœĐ°Ń‚ĐŸ ĐłŃ€ŃƒĐżĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} other {ĐŸŃ€ĐŸĐżŃƒŃĐœĐ°Ń‚ĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Đ“Đ»Đ°ŃĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ” бДз ĐŸŃ‚ĐłĐŸĐČĐŸŃ€} Video {ĐĐ”ĐŸŃ‚ĐłĐŸĐČĐŸŃ€Đ”ĐœĐŸ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”} Group {ĐĐ”ĐŸŃ‚ĐłĐŸĐČĐŸŃ€Đ”ĐœĐŸ ĐłŃ€ŃƒĐżĐŸĐČĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”} other {ĐĐ”ĐŸŃ‚ĐłĐŸĐČĐŸŃ€Đ”ĐœĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ОтĐșĐ°Đ·Đ°ĐœĐŸ ĐłĐ»Đ°ŃĐŸĐČĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”} Video {ОтĐșĐ°Đ·Đ°ĐœĐŸ ĐČĐžĐŽĐ”ĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”} Group {ОтĐșĐ°Đ·Đ°ĐœĐŸ ĐłŃ€ŃƒĐżĐŸĐČĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”} other {ОтĐșĐ°Đ·Đ°ĐœĐŸ ĐŸĐ±Đ°Đ¶ĐŽĐ°ĐœĐ”}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} Юруг Ń‡ĐŸĐČĐ”Đș пОшД.} other {{count,number} Юруго ЎушО пошат.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "КаĐșĐČĐŸ ĐœĐŸĐČĐŸ ĐžĐŒĐ°", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Đ”Ń€Đ”Đ±ĐœĐž ĐșĐŸŃ€Đ”Đșцоо, ĐżĐŸĐżŃ€Đ°ĐČĐșĐž ĐœĐ° Đ±ŃŠĐłĐŸĐČĐ” Đž ĐżĐŸĐŽĐŸĐ±Ń€Đ”ĐœĐžŃ ĐœĐ° Ń€Đ°Đ±ĐŸŃ‚Đ°Ń‚Đ°. Đ‘Đ»Đ°ĐłĐŸĐŽĐ°Ń€ĐžĐŒ ĐČĐž, чД ĐžĐ·ĐżĐŸĐ»Đ·ĐČатД Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "йазО аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·Đ°Ń†ĐžŃ ĐČĐșлючĐČа ĐœŃĐșĐŸĐ»ĐșĐŸ ĐżĐŸĐŽĐŸĐ±Ń€Đ”ĐœĐžŃ за ĐłĐ»Đ°ŃĐŸĐČĐž Đž ĐČĐžĐŽĐ”ĐŸ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž Đž ĐœŃĐșĐŸĐž ĐŽŃ€Đ”Đ±ĐœĐž аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·Đ°Ń†ĐžĐž ĐœĐ° ĐŽĐŸĐșŃƒĐŒĐ”ĐœŃ‚Đ°Ń†ĐžŃŃ‚Đ° (Đ±Đ»Đ°ĐłĐŸĐŽĐ°Ń€ĐžĐŒ ĐœĐ° {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "ВДчД ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐżŃ€ĐŸĐŒĐ”ĐœĐžŃ‚Đ” ĐžĐ·Đ±Ń€Đ°ĐœĐžŃ ĐŸŃ‚ ĐČас ДзОĐș ĐČ Signal, бДз Ўа ĐżŃ€ĐŸĐŒĐ”ĐœŃŃ‚Đ” ŃĐžŃŃ‚Đ”ĐŒĐœĐžŃ‚Đ” сО ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž (ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž ĐœĐ° Signal > Đ’ŃŠĐœŃˆĐ”Đœ ĐČОЎ > ЕзОĐș)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ĐŸŃ€ĐŸĐŒĐ”ĐœĐžŃ…ĐŒĐ” ĐœŃĐșĐŸĐž ĐłŃ€ŃƒĐżĐŸĐČĐž ĐžĐșĐŸĐœĐž за ОзĐČĐ”ŃŃ‚ĐžŃ." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ĐšĐŸŃ€ĐžĐłĐžŃ€Đ°Ń…ĐŒĐ” ĐșратĐșĐŸ забаĐČŃĐœĐ”, ĐșĐŸĐ”Ń‚ĐŸ ĐżĐŸĐœŃĐșĐŸĐłĐ° сД ŃĐ»ŃƒŃ‡ĐČашД ĐČ macOS слДЎ ĐżŃ€ĐžŃŃŠĐ”ĐŽĐžĐœŃĐČĐ°ĐœĐ” ĐșŃŠĐŒ Đ»ĐŸĐ±Đž за Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ĐšĐŸŃ€ĐžĐłĐžŃ€Đ°Ń…ĐŒĐ” Đ°ĐœĐžĐŒĐ°Ń†ĐžŃŃ‚Đ° за ĐżŃ€Đ”Ń…ĐŸĐŽ за ĐČĐžĐŽĐ”ĐŸĐżĐ»ĐŸŃ‡ĐșĐž, ĐșĐŸĐłĐ°Ń‚ĐŸ ĐœŃĐșĐŸĐč сД ĐżŃ€ĐžŃŃŠĐ”ĐŽĐžĐœĐž ОлО ĐœĐ°ĐżŃƒŃĐœĐ” ĐłŃ€ŃƒĐżĐŸĐČĐŸ ĐżĐŸĐČĐžĐșĐČĐ°ĐœĐ”." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ВДчД ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐșлОĐșĐČатД ĐČърху ĐżŃ€ĐŸŃ„ĐžĐ»ĐœĐ° ŃĐœĐžĐŒĐșа ОлО ĐłŃ€ŃƒĐżĐŸĐČ Đ°ĐČатар ĐČ Đ·Đ°ĐłĐ»Đ°ĐČĐșата ĐœĐ° чата за бърз ĐŽĐŸŃŃ‚ŃŠĐż ĐŽĐŸ ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșОтД ĐœĐ° чата ОлО за прДглДЎ ĐœĐ° ĐœĐ”Ń€Đ°Đ·ĐłĐ»Đ”ĐŽĐ°ĐœĐžŃ‚Đ” ĐžŃŃ‚ĐŸŃ€ĐžĐž ĐŸŃ‚ Ń‚ĐŸĐ·Đž чат. Đ‘Đ»Đ°ĐłĐŸĐŽĐ°Ń€ĐžĐŒ, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/bn-BD/messages.json b/_locales/bn-BD/messages.json index 06679cc21b..cf7fc6c210 100644 --- a/_locales/bn-BD/messages.json +++ b/_locales/bn-BD/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àŠĄàŠŸàŠŸàŠŸàŠŹà§‡àŠž àŠ€à§àŠ°à§àŠŸàŠż", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àŠĄàŠŸàŠŸàŠŸàŠŹà§‡àŠœ àŠžàŠ‚àŠ•à§àŠ°àŠŸàŠšà§àŠ€ àŠàŠ•àŠŸàŠż àŠ€à§àŠ°à§àŠŸàŠż àŠŠà§‡àŠ–àŠŸ àŠŠàŠżà§Ÿà§‡àŠ›à§‡à„€ àŠ†àŠȘàŠšàŠż àŠ€à§àŠ°à§àŠŸàŠżàŠŸàŠż àŠ•àŠȘàŠż àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°à§‡àŠš àŠàŠŹàŠ‚ àŠžàŠźàŠžà§àŠŻàŠŸàŠŸàŠż àŠžàŠźàŠŸàŠ§àŠŸàŠšà§‡ àŠžàŠŸàŠčàŠŸàŠŻà§àŠŻ àŠ•àŠ°àŠ€à§‡ Signal àŠžàŠčàŠŸàŠŻàŠŒàŠ€àŠŸàŠ° àŠžàŠŸàŠ„à§‡ àŠŻà§‹àŠ—àŠŸàŠŻà§‹àŠ— àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°à§‡àŠšà„€ àŠ†àŠȘàŠšàŠŸàŠ° àŠŻàŠŠàŠż àŠàŠ–àŠšàŠ‡ Signal àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ° àŠ•àŠ°àŠŸàŠ° àŠȘà§àŠ°à§Ÿà§‹àŠœàŠš àŠčàŠŻàŠŒ, àŠ€àŠŹà§‡ àŠ†àŠȘàŠšàŠż àŠ†àŠȘàŠšàŠŸàŠ° àŠĄà§‡àŠŸàŠŸ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠ€à§‡ àŠȘàŠŸàŠ°à§‡àŠš àŠàŠŹàŠ‚ àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠšàŠŸàŠČু àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°à§‡àŠšà„€\n\nàŠàŠ–àŠŸàŠšà§‡ àŠ­àŠżàŠœàŠżàŠŸ àŠ•àŠ°àŠŸàŠ° àŠźàŠŸàŠ§à§àŠŻàŠźà§‡ àŠžàŠŸàŠȘà§‹àŠ°à§àŠŸà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠŻà§‹àŠ—àŠŸàŠŻà§‹àŠ— àŠ•àŠ°à§àŠš: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àŠžàŠ•àŠČ àŠĄà§‡àŠŸàŠŸ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČà§àŠš àŠàŠŹàŠ‚ àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àŠĄà§‡àŠŸàŠŸ àŠźà§àŠ›à§àŠš àŠàŠŹàŠ‚ àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àŠžà§àŠ„àŠŸàŠŻàŠŒà§€àŠ­àŠŸàŠŹà§‡ àŠžàŠŹ àŠ€àŠ„à§àŠŻ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡àŠš?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àŠàŠ‡ àŠĄàŠżàŠ­àŠŸàŠ‡àŠž àŠ„à§‡àŠ•à§‡ àŠ†àŠȘàŠšàŠŸàŠ° àŠŻàŠŸàŠŹàŠ€à§€à§Ÿ àŠźà§‡àŠžà§‡àŠœà§‡àŠ° àŠ‡àŠ€àŠżàŠčàŠŸàŠž àŠàŠŹàŠ‚ àŠźàŠżàŠĄàŠżàŠŻàŠŒàŠŸ àŠžà§àŠ„àŠŸàŠŻàŠŒà§€àŠ­àŠŸàŠŹà§‡ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸ àŠčàŠŹà§‡à„€ àŠ†àŠȘàŠšàŠż àŠàŠ‡ àŠĄàŠżàŠ­àŠŸàŠ‡àŠžàŠŸàŠż àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠČàŠżàŠ‚àŠ• àŠ•àŠ°àŠŸàŠ° àŠȘàŠ°à§‡ Signal àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ° àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€ àŠàŠŸàŠż àŠ†àŠȘàŠšàŠŸàŠ° àŠ«à§‹àŠš àŠ„à§‡àŠ•à§‡ àŠ•à§‹àŠšà§‹ àŠĄà§‡àŠŸàŠŸ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡ àŠšàŠŸà„€", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° àŠĄàŠŸàŠŸàŠŸàŠŹà§‡àŠœà§‡àŠ° àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁ Signal-àŠàŠ° àŠàŠ‡ àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠźàŠżàŠČে àŠšàŠŸà„€ àŠšàŠżàŠ¶à§àŠšàŠżàŠ€ àŠ•àŠ°à§àŠš àŠŻà§‡ àŠ†àŠȘàŠšàŠż àŠ†àŠȘàŠšàŠŸàŠ° àŠ•àŠźà§àŠȘàŠżàŠ‰àŠŸàŠŸàŠ°à§‡ Signal-àŠàŠ° àŠšàŠ€à§àŠš àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁ àŠ–à§àŠČàŠ›à§‡àŠšà„€", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&àŠ«àŠŸàŠ‡àŠČ", @@ -300,6 +316,70 @@ "messageformat": "àŠšà§àŠŻàŠŸàŠŸ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° 'àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź' àŠšàŠżà§Ÿà§‡ àŠ•àŠżàŠ›à§ àŠàŠ•àŠŸàŠŸ àŠžàŠźàŠžà§àŠŻàŠŸ àŠčà§Ÿà§‡àŠ›à§‡, àŠàŠŸàŠż àŠ†àŠ° àŠ†àŠȘàŠšàŠŸàŠ° àŠ…à§àŠŻàŠŸàŠ•àŠŸàŠ‰àŠšà§àŠŸà§‡àŠ° àŠœàŠšà§àŠŻ àŠŹàŠ°àŠŸàŠŠà§àŠŠ àŠ•àŠ°àŠŸ àŠšà§‡àŠ‡à„€ àŠ†àŠȘàŠšàŠż àŠ†àŠŹàŠŸàŠ° àŠšà§‡àŠ·à§àŠŸàŠŸ àŠ•àŠ°à§‡ àŠàŠŸàŠż àŠžà§‡àŠŸ àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°à§‡àŠš àŠŹàŠŸ àŠšàŠ€à§àŠš àŠàŠ•àŠŸàŠż àŠŹà§‡àŠ›à§‡ àŠšàŠżàŠšà„€", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àŠàŠ–àŠšàŠ‡ àŠ àŠżàŠ• àŠ•àŠ°à§àŠš", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° QR àŠ•à§‹àŠĄ àŠàŠŹàŠ‚ àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠźà§‡àŠ° àŠČàŠżàŠ‚àŠ•à§‡ àŠ•àŠżàŠ›à§ àŠàŠ•àŠŸàŠŸ àŠ­à§àŠČ àŠčàŠŻàŠŒà§‡àŠ›à§‡, àŠàŠŸàŠż àŠ†àŠ° àŠ•àŠŸàŠ°à§àŠŻàŠ•àŠ° àŠšàŠŻàŠŒà„€ àŠ…àŠšà§àŠŻàŠŠà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠ¶à§‡àŠŻàŠŒàŠŸàŠ° àŠ•àŠ°àŠŸàŠ° àŠœàŠšà§àŠŻ àŠàŠ•àŠŸàŠż àŠšàŠ€à§àŠš àŠČàŠżàŠ‚àŠ• àŠ€à§ˆàŠ°àŠż àŠ•àŠ°à§àŠšà„€", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àŠàŠ–àŠšàŠ‡ àŠ àŠżàŠ• àŠ•àŠ°à§àŠš", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àŠŸà§àŠŻàŠŸàŠŹ àŠŠà§‡àŠ–àŠŸàŠš", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àŠŸà§àŠŻàŠŸàŠŹ àŠČà§àŠ•àŠŸàŠš", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àŠàŠ•àŠŸàŠż àŠ€à§àŠ°à§àŠŸàŠż àŠŠà§‡àŠ–àŠŸ àŠŠàŠżà§Ÿà§‡àŠ›à§‡", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} àŠ…àŠȘàŠ àŠżàŠ€", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àŠ…àŠȘàŠ àŠżàŠ€ àŠčàŠżàŠžà§‡àŠŹà§‡ àŠšàŠżàŠčà§àŠšàŠżàŠ€ àŠ•àŠ°àŠŸ àŠčàŠŻàŠŒà§‡àŠ›à§‡", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àŠšà§àŠŻàŠŸàŠŸ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àŠ•àŠČ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àŠžà§àŠŸà§‹àŠ°àŠż", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àŠžà§‡àŠŸàŠżàŠ‚àŠž", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal àŠ†àŠȘàŠĄà§‡àŠŸ àŠ•àŠ°à§àŠš", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àŠȘà§àŠ°à§‹àŠ«àŠŸàŠ‡àŠČ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àŠ«àŠżàŠ°à§‡ àŠŻàŠŸàŠš", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àŠàŠ‡ àŠšà§àŠŻàŠŸàŠŸàŠ—à§àŠČো àŠ†àŠ°à§àŠ•àŠŸàŠ‡àŠ­ àŠ•àŠ°àŠŸ àŠ†àŠ›à§‡ àŠàŠŹàŠ‚ àŠ¶à§àŠ§à§ àŠšàŠ€à§àŠš àŠźà§àŠŻàŠŸàŠžà§‡àŠœ àŠ†àŠžàŠČà§‡àŠ‡ àŠàŠ—à§àŠČো àŠ‡àŠšàŠŹàŠ•à§àŠžà§‡ àŠŠà§‡àŠ–àŠŸ àŠŻàŠŸàŠŹà§‡à„€", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àŠ€àŠŸàŠ°àŠȘàŠ°àŠ“ àŠ•àŠČ àŠ•àŠ°à§àŠš", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àŠ€àŠŸàŠ°àŠȘàŠ°àŠ“ àŠŻà§‹àŠ— àŠŠàŠżàŠš", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àŠ•àŠČ àŠšàŠŸàŠČàŠżà§Ÿà§‡ àŠŻàŠŸàŠš", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ°àŠ—à§àŠČো àŠ†àŠȘàŠĄà§‡àŠŸ àŠ•àŠ°àŠŸ àŠčàŠšà§àŠ›à§‡à„€", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àŠ†àŠ°àŠ“ àŠœàŠŸàŠšà§àŠš", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àŠȘà§‚àŠ°à§àŠŹàŠŹàŠ°à§àŠ€à§€ àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ°", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àŠȘàŠ°àŠŹàŠ°à§àŠ€à§€ àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ°", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ°à§‡àŠ° àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁ, {total,number}-àŠàŠ° àŠźàŠ§à§àŠŻà§‡ {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àŠŻàŠŸàŠšàŠŸàŠ‡àŠ•à§ƒàŠ€ àŠčàŠżàŠžà§‡àŠŹà§‡ àŠšàŠżàŠčà§àŠšàŠżàŠ€ àŠ•àŠ°à§àŠš", @@ -663,33 +747,41 @@ "messageformat": "àŠŻàŠŸàŠšàŠŸàŠ‡àŠ•àŠ°àŠŁ àŠžàŠźà§àŠȘà§‚àŠ°à§àŠŁ àŠ•àŠ°à§àŠš", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name}-àŠàŠ° àŠžàŠŸàŠ„à§‡ àŠàŠšà§àŠĄ-àŠŸà§-àŠàŠšà§àŠĄ àŠàŠšàŠ•à§àŠ°àŠżàŠȘàŠ¶àŠš àŠŻàŠŸàŠšàŠŸàŠ‡ àŠ•àŠ°àŠ€à§‡, àŠ€àŠŸàŠŠà§‡àŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠžà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠ‰àŠȘàŠ°à§‡àŠ° àŠšàŠźà§àŠŹàŠ°àŠ—à§àŠČো àŠ€à§àŠČàŠšàŠŸ àŠ•àŠ°à§àŠšà„€ àŠ€àŠŸàŠ°àŠŸàŠ“ àŠ€àŠŸàŠŠà§‡àŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠž àŠŠàŠżàŠŻàŠŒà§‡ àŠ†àŠȘàŠšàŠŸàŠ° àŠ•à§‹àŠĄ àŠžà§àŠ•à§àŠŻàŠŸàŠš àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àŠ†àŠ°à§‹ àŠœàŠŸàŠšà§àŠš", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name}-àŠàŠ° àŠžàŠŸàŠ„à§‡ àŠàŠšà§àŠĄ-àŠŸà§-àŠàŠšà§àŠĄ àŠàŠšàŠ•à§àŠ°àŠżàŠȘàŠ¶àŠš àŠŻàŠŸàŠšàŠŸàŠ‡ àŠ•àŠ°àŠ€à§‡, àŠ€àŠŸàŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠžà§‡àŠ° àŠ‰àŠȘàŠ°à§‡ àŠ„àŠŸàŠ•àŠŸ àŠ°àŠ™àŠżàŠš àŠ•àŠŸàŠ°à§àŠĄàŠŸàŠż àŠźàŠżàŠČàŠżà§Ÿà§‡ àŠŠà§‡àŠ–à§àŠš àŠàŠŹàŠ‚ àŠšàŠźà§àŠŹàŠ°àŠ—à§àŠČো àŠ€à§àŠČàŠšàŠŸ àŠ•àŠ°à§àŠšà„€ àŠŻàŠŠàŠż àŠàŠ—à§àŠČো àŠšàŠŸ àŠźàŠżàŠČে, àŠ€àŠŹà§‡ àŠ…àŠšà§àŠŻ àŠ†àŠ°à§‡àŠ• àŠœà§‹àŠĄàŠŒàŠŸ àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ° àŠ•àŠ°à§‡ àŠšà§‡àŠ·à§àŠŸàŠŸ àŠ•àŠ°à§àŠšà„€ àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° àŠàŠ•àŠŸàŠż àŠœà§‹à§œàŠŸ àŠźàŠżàŠČàŠ€à§‡ àŠčàŠŹà§‡à„€", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name}-àŠàŠ° àŠžàŠŸàŠ„à§‡ àŠàŠšà§àŠĄ-àŠŸà§-àŠàŠšà§àŠĄ àŠàŠšàŠ•à§àŠ°àŠżàŠȘàŠ¶àŠš àŠŻàŠŸàŠšàŠŸàŠ‡ àŠ•àŠ°àŠ€à§‡, àŠ€àŠŸàŠŠà§‡àŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠžà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠ‰àŠȘàŠ°à§‡àŠ° àŠšàŠźà§àŠŹàŠ°àŠ—à§àŠČো àŠ€à§àŠČàŠšàŠŸ àŠ•àŠ°à§àŠšà„€ àŠ€àŠŸàŠ°àŠŸàŠ“ àŠ€àŠŸàŠŠà§‡àŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠž àŠŠàŠżàŠŻàŠŒà§‡ àŠ†àŠȘàŠšàŠŸàŠ° àŠ•à§‹àŠĄ àŠžà§àŠ•à§àŠŻàŠŸàŠš àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠš àŠ•àŠ°à§àŠš", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal-àŠ àŠ†àŠžàŠšà§àŠš àŠ—à§‹àŠȘàŠšà§€àŠŻàŠŒàŠ€àŠŸ àŠ«àŠżàŠšàŠŸàŠ°àŠ—à§àŠČà§‹àŠ•à§‡ àŠžàŠšàŠČ àŠ•àŠ°àŠŸàŠ° àŠœàŠšà§àŠŻ àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠšà§‡àŠ° àŠžàŠźà§Ÿ àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ°àŠ—à§àŠČো àŠ†àŠȘàŠĄà§‡àŠŸ àŠ•àŠ°àŠŸ àŠčàŠšà§àŠ›à§‡à„€", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠŻàŠŸàŠšàŠŸàŠ‡ àŠ•àŠ°àŠ€à§‡, àŠ†àŠȘàŠšàŠŸàŠ° àŠ•àŠšà§àŠŸàŠŸàŠ•à§àŠŸà§‡àŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠžà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠ„àŠŸàŠ•àŠŸ àŠ°àŠ™àŠżàŠš àŠ•àŠŸàŠ°à§àŠĄàŠŸàŠż àŠźàŠżàŠČàŠżà§Ÿà§‡ àŠŠà§‡àŠ–à§àŠšà„€ àŠŻàŠŠàŠż àŠàŠ—à§àŠČো àŠšàŠŸ àŠźàŠżàŠČে, àŠ€àŠŹà§‡ àŠ…àŠšà§àŠŻ àŠ†àŠ°à§‡àŠ• àŠœà§‹àŠĄàŠŒàŠŸ àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ° àŠ•àŠ°à§‡ àŠšà§‡àŠ·à§àŠŸàŠŸ àŠ•àŠ°à§àŠšà„€ àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° àŠàŠ•àŠŸàŠż àŠœà§‹à§œàŠŸ àŠźàŠżàŠČàŠ€à§‡ àŠčàŠŹà§‡à„€", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àŠžàŠŸàŠčàŠŸàŠŻà§àŠŻ àŠȘà§àŠ°à§Ÿà§‹àŠœàŠš?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àŠŹà§àŠàŠ€à§‡ àŠȘà§‡àŠ°à§‡àŠ›àŠż", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àŠ†àŠȘàŠšàŠż àŠàŠ‡ àŠŹà§àŠŻàŠ•à§àŠ€àŠżàŠ° àŠžàŠŸàŠ„à§‡ àŠźà§‡àŠžà§‡àŠœ àŠŹàŠżàŠšàŠżàŠźàŠŻàŠŒ àŠ•àŠ°àŠŸàŠ° àŠȘàŠ°à§‡ àŠàŠ•àŠŸàŠż àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠ€à§ˆàŠ°àŠż àŠ•àŠ°àŠŸ àŠčàŠŹà§‡à„€", @@ -1267,10 +1359,6 @@ "messageformat": "àŠžàŠŸàŠźà§àŠȘà§àŠ°àŠ€àŠżàŠ• àŠźàŠżàŠĄàŠżà§ŸàŠŸ àŠŠà§‡àŠ–à§àŠš", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name}-àŠàŠ° àŠžàŠŸàŠ„à§‡ àŠ†àŠȘàŠšàŠŸàŠ° àŠàŠšà§àŠĄ-àŠŸà§-àŠàŠšà§àŠĄ àŠàŠšàŠ•à§àŠ°àŠżàŠȘàŠ¶àŠšà§‡àŠ° àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠŻàŠŸàŠšàŠŸàŠ‡ àŠ•àŠ°àŠ€à§‡, àŠ€àŠŸàŠŠà§‡àŠ° àŠĄàŠżàŠ­àŠŸàŠ‡àŠžà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠ‰àŠȘàŠ°à§‡àŠ° àŠšàŠźà§àŠŹàŠ°àŠ—à§àŠČো àŠ€à§àŠČàŠšàŠŸ àŠ•àŠ°à§àŠšà„€ àŠ€àŠŸàŠ°àŠŸàŠ“ àŠ‰àŠȘàŠ°à§‡àŠ° QR àŠ•à§‹àŠĄàŠŸàŠż àŠžà§àŠ•à§àŠŻàŠŸàŠš àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àŠ†àŠȘàŠšàŠż àŠàŠ‡ àŠȘàŠ°àŠżàŠšàŠżàŠ€àŠż àŠàŠ° àŠžàŠŸàŠ„à§‡ àŠ•à§‹àŠšàŠ“ àŠŹàŠŸàŠ°à§àŠ€àŠŸ àŠŹàŠżàŠšàŠżàŠźàŠŻàŠŒ àŠ•àŠ°à§‡àŠšàŠšàŠżà„€ àŠ€àŠŸàŠŠà§‡àŠ° àŠžàŠŸàŠ„à§‡ àŠ†àŠȘàŠšàŠŸàŠ° àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠŸàŠźà§àŠŹàŠŸàŠ° àŠȘà§àŠ°àŠ„àŠź àŠŹàŠŸàŠ°à§àŠ€àŠŸ àŠȘàŠŸàŠ àŠŸàŠšà§‹àŠ° àŠȘàŠ°à§‡ àŠȘàŠŸàŠ“à§ŸàŠŸ àŠŻàŠŸàŠšà§àŠ›à§‡à„€" }, @@ -1334,17 +1422,17 @@ "messageformat": "àŠ€àŠ„à§àŠŻ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àŠźà§àŠ›à§‡ àŠ«à§‡àŠČà§àŠš", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àŠźà§‡àŠžà§‡àŠœ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČà§àŠš", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àŠšà§àŠŻàŠŸàŠŸ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡àŠš?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àŠźà§‡àŠžà§‡àŠœ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡àŠš?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àŠàŠ‡ àŠšà§àŠŻàŠŸàŠŸàŠŸàŠż àŠàŠ‡ àŠĄàŠżàŠ­àŠŸàŠ‡àŠž àŠ„à§‡àŠ•à§‡ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸ àŠčàŠŹà§‡à„€", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àŠàŠ‡ àŠšà§àŠŻàŠŸàŠŸà§‡àŠ° àŠźà§‡àŠžà§‡àŠœàŠ—à§àŠČো àŠàŠ‡ àŠĄàŠżàŠ­àŠŸàŠ‡àŠž àŠ„à§‡àŠ•à§‡ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸ àŠčàŠŹà§‡à„€ àŠźà§‡àŠžà§‡àŠœàŠ—à§àŠČো àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸàŠ° àŠȘàŠ°à§‡àŠ“ àŠ†àŠȘàŠšàŠż àŠàŠ‡ àŠšà§àŠŻàŠŸàŠŸàŠŸàŠż àŠ…àŠšà§àŠžàŠšà§àŠ§àŠŸàŠš àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àŠ—à§àŠ°à§àŠȘ àŠ€à§àŠŻàŠŸàŠ— àŠ•àŠ°à§àŠš", @@ -1438,6 +1526,14 @@ "messageformat": "àŠ‰àŠ­àŠŻàŠŒ àŠšà§àŠŻàŠŸàŠŸ-àŠàŠ° àŠœàŠšà§àŠŻ àŠ†àŠȘàŠšàŠŸàŠ° àŠźà§àŠŻàŠŸàŠžà§‡àŠœà§‡àŠ° àŠ‡àŠ€àŠżàŠčàŠŸàŠž àŠàŠ–àŠŸàŠšà§‡ àŠàŠ•àŠ€à§àŠ°àŠżàŠ€ àŠ•àŠ°àŠŸ àŠčàŠŻàŠŒà§‡àŠ›à§‡à„€", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} àŠšàŠźà§àŠŹàŠ°àŠŸàŠż {conversationTitle}-àŠàŠ°à„€ àŠ†àŠȘàŠšàŠŸàŠ°àŠŸ àŠŠà§àŠœàŠšàŠ‡ {sharedGroup} àŠ—à§à§°à§àŠȘà§‡àŠ° àŠžàŠŠàŠžà§àŠŻà„€", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} àŠšàŠźà§àŠŹàŠ°àŠŸàŠż {conversationTitle}-àŠàŠ°à„€", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àŠ›àŠŹàŠż àŠàŠŹàŠ‚ àŠ‰àŠŠà§àŠ§à§ƒàŠ€ àŠźà§‡àŠžà§‡àŠœà§‡àŠ° àŠ„àŠŸàŠźà§àŠŹàŠšà§‡àŠ‡àŠČ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àŠ†àŠŹàŠŸàŠ° àŠ•àŠČ àŠ•àŠ°à§àŠš", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àŠ•àŠČ àŠ¶à§àŠ°à§ àŠ•àŠ°à§àŠš", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àŠ•àŠČে àŠŻà§‹àŠ— àŠŠàŠżàŠš", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àŠ•àŠČà§‡àŠ° àŠ†àŠ•àŠŸàŠ°à§‡àŠ° àŠ•àŠŸàŠ°àŠŁà§‡ àŠźàŠŸàŠ‡àŠ•à§àŠ°à§‹àŠ«à§‹àŠš àŠźàŠżàŠ‰àŠŸ àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àŠ•àŠČ àŠšà§‹àŠŸàŠżàŠ«àŠżàŠ•à§‡àŠ¶àŠš", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àŠ•àŠČàŠŸàŠżàŠ€à§‡ àŠœàŠŸà§ŸàŠ—àŠŸ àŠšà§‡àŠ‡", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àŠ•à§àŠŻàŠŸàŠźà§‡àŠ°àŠŸ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àŠŻà§‹àŠ—àŠŠàŠŸàŠš àŠ•àŠ°à§àŠš", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àŠ¶à§àŠ°à§ àŠ•àŠ°à§àŠš", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àŠ•àŠČàŠŸàŠżàŠ€à§‡ àŠœàŠŸà§ŸàŠ—àŠŸ àŠšà§‡àŠ‡", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àŠ•à§àŠŻàŠŸàŠźà§‡àŠ°àŠŸ àŠšàŠżàŠ·à§àŠ•à§àŠ°àŠżà§Ÿ àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡", @@ -1621,10 +1725,6 @@ "messageformat": "àŠ•à§àŠŻàŠŸàŠźà§‡àŠ°àŠŸ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àŠźàŠżàŠ‰àŠŸ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àŠźàŠŸàŠ‡àŠ•à§àŠ°à§‹àŠ«à§‹àŠš àŠšàŠżàŠ·à§àŠ•à§àŠ°àŠżà§Ÿ àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àŠźàŠŸàŠ‡àŠ• àŠ†àŠšàŠźàŠżàŠ‰àŠŸ àŠ•àŠ°à§àŠš", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àŠ¶à§‡à§ŸàŠŸàŠ° àŠ•àŠ°à§àŠš", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àŠ‰àŠȘàŠžà§àŠ„àŠŸàŠȘàŠšàŠŸ àŠšàŠżàŠ·à§àŠ•à§àŠ°àŠżà§Ÿ àŠ•àŠ°àŠŸ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àŠ‰àŠȘàŠžà§àŠ„àŠŸàŠȘàŠšàŠŸ àŠ„àŠŸàŠźàŠŸàŠš", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àŠ°àŠżàŠ‚", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àŠ…àŠ‚àŠ¶àŠ—à§àŠ°àŠčàŠŁàŠ•àŠŸàŠ°à§€àŠŠà§‡àŠ° àŠ•àŠČ àŠ•àŠ°àŠŸàŠ° àŠœàŠšà§àŠŻ àŠ—à§àŠ°à§àŠȘàŠŸàŠż àŠ–à§àŠŹ àŠŹàŠĄàŠŒ", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àŠ°àŠżàŠ‚ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àŠ°àŠżàŠ‚ àŠŹàŠšà§àŠ§ àŠ•àŠ°à§àŠš", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àŠ°àŠżàŠ‚ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àŠ†àŠ°à§‹ àŠ…àŠȘàŠ¶àŠš", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àŠ†àŠȘàŠšàŠż", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° àŠ•à§àŠŻàŠŸàŠźà§‡àŠ°àŠŸ àŠŹàŠšà§àŠ§ àŠ°à§Ÿà§‡àŠ›à§‡", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠŠà§‡àŠ–à§àŠš", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àŠźà§‡àŠžà§‡àŠœ àŠȘàŠŸàŠ àŠŸàŠš", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àŠšàŠżàŠ°àŠŸàŠȘàŠ€à§àŠ€àŠŸ àŠšàŠźà§àŠŹàŠ° àŠŠà§‡àŠ–à§àŠš", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "àŠ«à§‹àŠš àŠšàŠŸàŠźà§àŠŹàŠŸàŠ° àŠ†àŠšàŠŸ àŠžàŠ«àŠČ àŠčà§ŸàŠšàŠżà„€ àŠ†àŠȘàŠšàŠŸàŠ° àŠ‡àŠšà§àŠŸàŠŸàŠ°àŠšà§‡àŠŸ àŠžàŠ‚àŠŻà§‹àŠ— àŠ àŠżàŠ• àŠ†àŠ›à§‡ àŠ•àŠżàŠšàŠŸ àŠŠà§‡àŠ–à§àŠš àŠàŠŹàŠ‚ àŠ†àŠŹàŠŸàŠ° àŠšà§‡àŠ·à§àŠŸàŠŸ àŠ•àŠ°à§àŠšà„€", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àŠàŠ‡ àŠźà§àŠŻàŠŸàŠžà§‡àŠœàŠŸàŠż àŠȘàŠŸàŠ àŠŸàŠšà§‹àŠ° àŠȘàŠ°àŠŹàŠ°à§àŠ€à§€ 3 àŠ˜àŠšà§àŠŸàŠŸàŠ° àŠźàŠ§à§àŠŻà§‡ àŠàŠĄàŠżàŠŸ àŠ•àŠ°àŠŸ àŠŻàŠŸàŠŹà§‡à„€", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àŠàŠ‡ àŠźà§àŠŻàŠŸàŠžà§‡àŠœàŠŸàŠż àŠȘàŠŸàŠ àŠŸàŠšà§‹àŠ° àŠȘàŠ° àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° àŠȘàŠ°àŠŹàŠ°à§àŠ€à§€ 24 àŠ˜àŠšà§àŠŸàŠŸàŠ° àŠźàŠ§à§àŠŻà§‡ àŠàŠŸàŠż àŠàŠĄàŠżàŠŸ àŠ•àŠ°àŠŸ àŠŻàŠŸàŠŹà§‡à„€", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àŠàŠ‡ àŠźà§‡àŠžà§‡àŠœàŠŸàŠż àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸ àŠčàŠŻàŠŒà§‡àŠ›à§‡à„€", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àŠžàŠ‚àŠŻà§àŠ•à§àŠ€àŠżàŠŸàŠż àŠŹà§‡àŠ¶àŠż àŠŹà§œ àŠ€àŠŸàŠ‡ àŠŠà§‡àŠ–àŠŸàŠšà§‹ àŠŻàŠŸàŠšà§àŠ›à§‡ àŠšàŠŸà„€", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àŠ•àŠżàŠ›à§ àŠ•àŠżàŠ›à§ àŠžàŠ‚àŠŻà§àŠ•à§àŠ€àŠż àŠàŠ€àŠŸàŠŸàŠ‡ àŠŹà§œ àŠ„àŠŸàŠ•à§‡ àŠŻà§‡ àŠ€àŠŸ àŠŠà§‡àŠ–àŠŸàŠšà§‹ àŠŻàŠŸà§Ÿ àŠšàŠŸà„€", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àŠĄà§‹àŠšà§‡àŠ¶àŠšà§‡àŠ° àŠŹàŠżàŠžà§àŠ€àŠŸàŠ°àŠżàŠ€ àŠ€àŠ„à§àŠŻ àŠžàŠ‚àŠ—à§àŠ°àŠč àŠ•àŠ°àŠŸ àŠžàŠźà§àŠ­àŠŹ àŠčà§ŸàŠšàŠż", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° Signal àŠŹàŠżàŠŸàŠŸ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° Signal àŠŹàŠżàŠŸàŠŸ àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ—àŠŁ àŠźà§àŠŻàŠŸàŠžà§‡àŠœ àŠàŠĄàŠżàŠŸ àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€ àŠ†àŠȘàŠšàŠż àŠŻàŠŠàŠż àŠ•à§‹àŠšà§‹ àŠźà§àŠŻàŠŸàŠžà§‡àŠœ àŠàŠĄàŠżàŠŸ àŠ•àŠ°à§‡àŠš, àŠ€àŠŹà§‡ àŠàŠŸàŠż àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° Signal àŠŹàŠżàŠŸàŠŸàŠ° àŠžàŠ°à§àŠŹàŠ¶à§‡àŠ· àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁ àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠŠà§‡àŠ° àŠ•àŠŸàŠ›à§‡ àŠŠà§ƒàŠ¶à§àŠŻàŠźàŠŸàŠš àŠčàŠŹà§‡à„€", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àŠźà§‡àŠžà§‡àŠœ àŠàŠĄàŠżàŠŸ àŠ•àŠ°à§àŠš", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àŠ†àŠȘàŠšàŠż àŠŻàŠŠàŠż àŠ•à§‹àŠšà§‹ àŠźà§‡àŠžà§‡àŠœ àŠàŠĄàŠżàŠŸ àŠ•àŠ°à§‡àŠš, àŠ€àŠŹà§‡ àŠàŠŸàŠż àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° Signal-àŠàŠ° àŠžàŠ°à§àŠŹàŠ¶à§‡àŠ· àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁ àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠŠà§‡àŠ° àŠ•àŠŸàŠ›à§‡ àŠŠà§ƒàŠ¶à§àŠŻàŠźàŠŸàŠš àŠčàŠŹà§‡à„€ àŠ†àŠȘàŠšàŠż àŠŻà§‡ àŠàŠ•àŠŸàŠż àŠźà§‡àŠžà§‡àŠœ àŠàŠĄàŠżàŠŸ àŠ•àŠ°à§‡àŠ›à§‡àŠš àŠ€àŠŸàŠ°àŠŸ àŠ€àŠŸ àŠŠà§‡àŠ–àŠ€à§‡ àŠȘàŠŸàŠŹà§‡àŠšà„€", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àŠ‡àŠšàŠ•àŠŸàŠźàŠżàŠ‚ àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àŠ­à§Ÿà§‡àŠž àŠ•àŠČ àŠŻàŠŸàŠšà§àŠ›à§‡", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ àŠŻàŠŸàŠšà§àŠ›à§‡", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àŠ†àŠȘàŠšàŠŸàŠ•à§‡ àŠ•àŠČ àŠ•àŠ°àŠ›à§‡", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àŠ†àŠŹàŠŸàŠ°à§‹ àŠžàŠ‚àŠŻà§àŠ•à§àŠ€ àŠ•àŠ°àŠŸ àŠčàŠšà§àŠ›à§‡â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} àŠźàŠŸàŠšà§àŠ·} other {{count,number} àŠźàŠŸàŠšà§àŠ·}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àŠ…àŠĄàŠżàŠ“ àŠ•àŠČ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àŠ¶à§‡àŠ·", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àŠ€à§àŠŻàŠŸàŠ— àŠ•àŠ°à§àŠš", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àŠźàŠŸàŠ‡àŠ• àŠŹàŠšà§àŠ§ àŠ•àŠ°à§àŠš", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àŠźàŠŸàŠ‡àŠ• àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àŠ°àŠżàŠ‚ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àŠ°àŠżàŠ‚ àŠŹàŠšà§àŠ§ àŠ•àŠ°à§àŠš", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àŠžà§‡àŠŸàŠżàŠ‚àŠž", @@ -3468,13 +3668,25 @@ "messageformat": "àŠȘà§‚àŠ°à§àŠŁàŠžà§àŠ•à§àŠ°àŠżàŠšà§‡ àŠ•àŠČ àŠ•àŠ°à§àŠš", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àŠ—à§àŠ°àŠżàŠĄ àŠ­àŠżàŠ‰àŠ€à§‡ àŠȘàŠŸàŠČà§àŠŸàŠŸàŠš", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àŠ­àŠżàŠ‰ àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠš àŠ•àŠ°à§àŠš", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àŠžà§àŠȘàŠżàŠ•àŠŸàŠ° àŠ­àŠżàŠ‰àŠ€à§‡ àŠȘàŠŸàŠČà§àŠŸàŠŸàŠš", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àŠ—à§àŠ°àŠżàŠĄ àŠ­àŠżàŠ‰", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àŠžàŠŸàŠ‡àŠĄàŠŹàŠŸàŠ° àŠ­àŠżàŠ‰", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àŠžà§àŠȘàŠżàŠ•àŠŸàŠ° àŠ­àŠżàŠ‰", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àŠ­àŠżàŠ‰ àŠ†àŠȘàŠĄà§‡àŠŸ àŠ•àŠ°àŠŸ àŠčàŠŻàŠŒà§‡àŠ›à§‡", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àŠ•àŠČ àŠ›à§‡à§œà§‡ àŠŻàŠŸàŠš", @@ -3576,6 +3788,14 @@ "messageformat": "àŠ àŠżàŠ• àŠ†àŠ›à§‡", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àŠźà§‡àŠžà§‡àŠœ àŠàŠĄàŠżàŠŸ àŠ•àŠ°àŠŸ àŠŻàŠŸàŠŹà§‡ àŠšàŠŸ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àŠàŠ‡ àŠźà§‡àŠžà§‡àŠœàŠŸàŠż àŠ¶à§àŠ§à§àŠźàŠŸàŠ€à§àŠ° {max,number} àŠŹàŠŸàŠ° àŠàŠĄàŠżàŠŸ àŠ•àŠ°àŠŸ àŠŻàŠŸàŠŹà§‡à„€", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àŠŠà§àŠƒàŠ–àŠżàŠ€, àŠŻà§‡ sgnl:// àŠČàŠżàŠ‚àŠ•àŠŸàŠż àŠ‰àŠȘàŠŻà§àŠ•à§àŠ€ àŠ›àŠżàŠČ àŠšàŠŸ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àŠ‡àŠ‰àŠœàŠŸàŠ°àŠšà§‡àŠź", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° 'àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź' àŠšàŠżà§Ÿà§‡ àŠ•àŠżàŠ›à§ àŠàŠ•àŠŸàŠŸ àŠžàŠźàŠžà§àŠŻàŠŸ àŠčà§Ÿà§‡àŠ›à§‡, àŠàŠŸàŠż àŠ†àŠ° àŠ†àŠȘàŠšàŠŸàŠ° àŠ…à§àŠŻàŠŸàŠ•àŠŸàŠ‰àŠšà§àŠŸà§‡àŠ° àŠœàŠšà§àŠŻ àŠŹàŠ°àŠŸàŠŠà§àŠŠ àŠ•àŠ°àŠŸ àŠšà§‡àŠ‡à„€", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź àŠźà§àŠ›à§‡ àŠ«à§‡àŠČà§àŠš", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àŠ‡àŠ‰àŠœàŠŸàŠ°àŠšà§‡àŠź àŠ€à§ˆàŠ°àŠż àŠ•àŠ°à§àŠš", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR àŠ•à§‹àŠĄ àŠŹàŠŸ àŠČàŠżàŠ‚àŠ•", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź àŠ°àŠżàŠžà§‡àŠŸ àŠ•àŠ°àŠŸ àŠȘà§àŠ°àŠŻàŠŒà§‹àŠœàŠš", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠźà§‡àŠ° àŠČàŠżàŠ‚àŠ• àŠ°àŠżàŠžà§‡àŠŸ àŠ•àŠ°àŠŸ àŠȘà§àŠ°àŠŻàŠŒà§‹àŠœàŠš", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° 'àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź' àŠ¶à§‡à§ŸàŠŸàŠ° àŠ•àŠ°à§àŠš", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź àŠźà§àŠ›à§‡ àŠ«à§‡àŠČà§àŠš", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àŠàŠŸàŠż àŠ†àŠȘàŠšàŠŸàŠ° àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡, àŠŻàŠŸ àŠ…àŠšà§àŠŻ àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠŠà§‡àŠ° àŠàŠ‡ àŠšàŠŸàŠźàŠŸàŠż àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ° àŠ•àŠ°àŠ€à§‡ àŠŠàŠżàŠŹà§‡à„€ àŠ†àŠȘàŠšàŠż àŠ•àŠż àŠšàŠżàŠ¶à§àŠšàŠżàŠ€?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àŠàŠŸàŠż àŠ†àŠȘàŠšàŠŸàŠ° àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡ àŠàŠŹàŠ‚ àŠ†àŠȘàŠšàŠŸàŠ° QR àŠ•à§‹àŠĄ àŠ“ àŠČàŠżàŠ‚àŠ• àŠ…àŠ•àŠŸàŠ°à§àŠŻàŠ•àŠ° àŠ•àŠ°àŠŹà§‡à„€ \"{username}\" àŠ…àŠšà§àŠŻàŠ°àŠŸ àŠŠàŠŸàŠŹàŠż àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€ àŠ†àŠȘàŠšàŠż àŠ•àŠż àŠšàŠżàŠ¶à§àŠšàŠżàŠ€?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àŠ†àŠȘàŠšàŠż àŠ†àŠ° àŠžà§àŠŸà§‹àŠ°àŠż àŠ¶à§‡àŠŻàŠŒàŠŸàŠ° àŠ•àŠ°àŠ€à§‡ àŠŹàŠŸ àŠŠà§‡àŠ–àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠš àŠšàŠŸà„€ àŠ†àŠȘàŠšàŠż àŠžàŠźà§àŠȘà§àŠ°àŠ€àŠż àŠ¶à§‡àŠŻàŠŒàŠŸàŠ° àŠ•àŠ°à§‡àŠ›à§‡àŠš àŠàŠźàŠš àŠžà§àŠŸà§‹àŠ°àŠżàŠ° àŠ†àŠȘàŠĄà§‡àŠŸàŠ—à§àŠČà§‹àŠ“ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸ àŠčàŠŹà§‡à§·", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àŠ­àŠŸàŠ·àŠŸ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àŠ­àŠŸàŠ·àŠŸ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àŠžàŠżàŠžà§àŠŸà§‡àŠźà§‡àŠ° àŠ­àŠŸàŠ·àŠŸ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àŠ­àŠŸàŠ·àŠŸ àŠ…àŠšà§àŠžàŠšà§àŠ§àŠŸàŠš àŠ•àŠ°à§àŠš", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}”-àŠàŠ° àŠœàŠšà§àŠŻ àŠ•à§‹àŠšà§‹ àŠ«àŠČàŠŸàŠ«àŠČ àŠȘàŠŸàŠ“à§ŸàŠŸ àŠŻàŠŸà§ŸàŠšàŠż", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àŠžà§‡àŠŸ àŠ•àŠ°à§àŠš", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àŠ•àŠŸàŠ°à§àŠŻàŠ•àŠ° àŠ•àŠ°àŠ€à§‡ Signal àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àŠ­àŠŸàŠ·àŠŸ àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠš àŠ•àŠ°àŠ€à§‡, àŠ…à§àŠŻàŠŸàŠȘàŠŸàŠż àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠšàŠŸàŠČু àŠ•àŠ°àŠ€à§‡ àŠčàŠŹà§‡à„€", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠšàŠŸàŠČু àŠ•àŠ°à§àŠš", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} àŠžàŠčàŠœàŠČàŠ­à§àŠŻ àŠžàŠ‚àŠžà§àŠ•àŠ°àŠŁà§‡ àŠ†àŠȘàŠĄà§‡àŠŸ àŠ•àŠ°à§àŠš", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° àŠžà§‡àŠŸàŠżàŠ‚àŠž àŠžàŠ‚àŠ°àŠ•à§àŠ·àŠŁ àŠ•àŠ°àŠŸàŠ° àŠžàŠźàŠŻàŠŒ àŠàŠ•àŠŸàŠż àŠ€à§àŠ°à§àŠŸàŠż àŠ›àŠżàŠČà„€ àŠ…àŠšà§àŠ—à§àŠ°àŠčàŠȘà§‚àŠ°à§àŠŹàŠ• àŠ†àŠŹàŠŸàŠ° àŠšà§‡àŠ·à§àŠŸàŠŸ àŠ•àŠ°à§àŠšà„€", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àŠźà§‡àŠžà§‡àŠœ àŠȘàŠŸàŠ àŠŸàŠš", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àŠ†àŠ°à§‹ àŠžà§àŠŸàŠŸàŠ‡àŠČ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àŠ°àŠżàŠžà§‡àŠŸ àŠ•àŠ°à§àŠš", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àŠ¶à§‡àŠ·", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "'àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź' àŠČàŠżàŠ‚àŠ•à§‡àŠ° àŠ°àŠ‚, {total,number}-àŠàŠ° {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° 'àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ°àŠ•àŠŸàŠ°à§€àŠ° àŠšàŠŸàŠź' àŠ°àŠżàŠžà§‡àŠŸ àŠ•àŠ°àŠČে àŠ†àŠȘàŠšàŠŸàŠ° àŠŹàŠżàŠŠà§àŠŻàŠźàŠŸàŠš QR àŠ•à§‹àŠĄ àŠ“ àŠČàŠżàŠ‚àŠ• àŠ†àŠ° àŠ•àŠŸàŠœ àŠ•àŠ°àŠŹà§‡ àŠšàŠŸà„€", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àŠČàŠżàŠ‚àŠ•àŠŸàŠż àŠȘà§àŠšàŠ°àŠŸàŠŻàŠŒ àŠžà§‡àŠŸ àŠ•àŠ°àŠŸ àŠčàŠšà§àŠ›à§‡...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR àŠ•à§‹àŠĄ àŠàŠŹàŠ‚ àŠČàŠżàŠ‚àŠ• àŠžà§‡àŠŸ àŠ•àŠ°àŠŸ àŠčàŠŻàŠŒàŠšàŠżà„€ àŠ†àŠȘàŠšàŠŸàŠ° àŠšà§‡àŠŸàŠ“àŠŻàŠŒàŠŸàŠ°à§àŠ• àŠžàŠ‚àŠŻà§‹àŠ— àŠ àŠżàŠ• àŠ†àŠ›à§‡ àŠ•àŠż àŠšàŠŸ àŠŠà§‡àŠ–à§àŠš àŠàŠŹàŠ‚ àŠ†àŠŹàŠŸàŠ° àŠšà§‡àŠ·à§àŠŸàŠŸ àŠ•àŠ°à§àŠšà„€", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àŠ†àŠȘàŠšàŠŸàŠ° Signal 'àŠ‡àŠ‰àŠœàŠŸàŠ°àŠšà§‡àŠź' àŠžà§‡àŠŸ àŠ†àŠȘ àŠ•àŠ°à§àŠš", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "àŠ†àŠŹàŠŸàŠ° àŠȘàŠŸàŠ àŠŸàŠš", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àŠ†àŠ°àŠ“ àŠ•à§àŠ°àŠżà§ŸàŠŸ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àŠ•àŠČ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àŠšàŠ€à§àŠš àŠ•àŠČ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àŠšàŠ€à§àŠš àŠ•àŠČ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àŠ†àŠ°àŠ“ àŠ•à§àŠ°àŠżà§ŸàŠŸ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àŠ•àŠČà§‡àŠ° àŠ‡àŠ€àŠżàŠčàŠŸàŠž àŠźà§àŠ›à§‡ àŠ«à§‡àŠČà§àŠš", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àŠ•àŠČà§‡àŠ° àŠ‡àŠ€àŠżàŠčàŠŸàŠž àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡àŠš?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àŠàŠŸàŠż àŠ•àŠČà§‡àŠ° àŠžàŠ•àŠČ àŠ‡àŠ€àŠżàŠčàŠŸàŠž àŠžà§àŠ„àŠŸàŠŻàŠŒà§€àŠ­àŠŸàŠŹà§‡ àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŹà§‡", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àŠžàŠŸàŠ« àŠ•àŠ°à§àŠš", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àŠ•àŠČà§‡àŠ° àŠ‡àŠ€àŠżàŠčàŠŸàŠž àŠźà§àŠ›à§‡ àŠ«à§‡àŠČàŠŸ àŠčà§Ÿà§‡àŠ›à§‡", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àŠŠà§‡àŠ–àŠ€à§‡ àŠŹàŠŸ àŠ•àŠČ àŠ¶à§àŠ°à§ àŠ•àŠ°àŠ€à§‡ àŠ•à§àŠČàŠżàŠ• àŠ•àŠ°à§àŠš", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àŠ…àŠšà§àŠžàŠšà§àŠ§àŠŸàŠš", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àŠźàŠżàŠžàŠĄ àŠ•àŠČà§‡àŠ° àŠ‰àŠȘàŠ° àŠ­àŠżàŠ€à§àŠ€àŠż àŠ•àŠ°à§‡ àŠ«àŠżàŠČà§àŠŸàŠŸàŠ° àŠ•àŠ°à§àŠš", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àŠŸàŠ—àŠČ àŠ•àŠ°à§àŠš", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àŠ•à§‹àŠšà§‹ àŠžàŠŸàŠźà§àŠȘà§àŠ°àŠ€àŠżàŠ• àŠ•àŠČ àŠšà§‡àŠ‡à„€ àŠàŠ•àŠœàŠš àŠŹàŠšà§àŠ§à§àŠ•à§‡ àŠ•àŠČ àŠŠàŠżà§Ÿà§‡ àŠ¶à§àŠ°à§ àŠ•àŠ°à§àŠšà„€", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}”-àŠàŠ° àŠœàŠšà§àŠŻ àŠ•à§‹àŠšà§‹ àŠ«àŠČàŠŸàŠ«àŠČ àŠȘàŠŸàŠ“à§ŸàŠŸ àŠŻàŠŸà§ŸàŠšàŠż", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àŠ•àŠČ àŠ†àŠžàŠ›à§‡", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àŠ†àŠ‰àŠŸàŠ—à§‹àŠŻàŠŒàŠżàŠ‚ àŠ•àŠČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àŠźàŠżàŠžàŠĄ àŠ•àŠČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àŠ—à§àŠ°à§àŠȘ àŠ•àŠČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àŠ•à§‹àŠšà§‹ àŠžàŠŸàŠźà§àŠȘà§àŠ°àŠ€àŠżàŠ• àŠ•àŠ„à§‹àŠȘàŠ•àŠ„àŠš àŠšà§‡àŠ‡à„€", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}”-àŠàŠ° àŠœàŠšà§àŠŻ àŠ•à§‹àŠšà§‹ àŠ«àŠČàŠŸàŠ«àŠČ àŠȘàŠŸàŠ“à§ŸàŠŸ àŠŻàŠŸà§ŸàŠšàŠż", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àŠ­à§Ÿà§‡àŠž àŠ•àŠČ àŠŻàŠŸàŠšà§àŠ›à§‡} other {àŠ­à§Ÿà§‡àŠž àŠ•àŠČ àŠ†àŠžàŠ›à§‡}}} Video {{direction, select, Outgoing {àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ àŠŻàŠŸàŠšà§àŠ›à§‡} other {àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ àŠ†àŠžàŠ›à§‡}}} Group {{direction, select, Outgoing {àŠ†àŠ‰àŠŸàŠ—à§‹à§ŸàŠżàŠ‚ àŠ—à§àŠ°à§àŠȘ àŠ•àŠČ} other {àŠ‡àŠšàŠ•àŠŸàŠźàŠżàŠ‚ àŠ—à§àŠ°à§àŠȘ àŠ•àŠČ}}} other {{direction, select, Outgoing {àŠ†àŠ‰àŠŸàŠ—à§‹àŠŻàŠŒàŠżàŠ‚ àŠ•àŠČ} other {àŠ†àŠ—àŠ€ àŠ•àŠČ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àŠźàŠżàŠžàŠĄ àŠ­à§Ÿà§‡àŠž àŠ•àŠČ} Video {àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ àŠźàŠżàŠž àŠčà§Ÿà§‡àŠ›à§‡} Group {àŠźàŠżàŠžàŠĄ àŠ—à§àŠ°à§àŠȘ àŠ•àŠČ} other {àŠŹà§àŠŻàŠ°à§àŠ„ àŠ•àŠČ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àŠ‰àŠ€à§àŠ€àŠ° àŠšàŠŸ àŠŠà§‡àŠ“à§ŸàŠŸ àŠ­à§Ÿà§‡àŠž àŠ•àŠČ} Video {àŠ‰àŠ€à§àŠ€àŠ° àŠšàŠŸ àŠŠà§‡àŠ“à§ŸàŠŸ àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ} Group {àŠ‰àŠ€à§àŠ€àŠ° àŠŠà§‡àŠ“à§ŸàŠŸ àŠčà§ŸàŠšàŠż àŠàŠźàŠš àŠ—à§à§°à§àŠȘ àŠ•àŠČ} other {àŠ‰àŠ€à§àŠ€àŠ° àŠŠà§‡àŠ“à§ŸàŠŸ àŠčà§ŸàŠšàŠż àŠàŠźàŠš àŠ•àŠČ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àŠȘà§àŠ°àŠ€à§àŠŻàŠŸàŠ–à§àŠŻàŠŸàŠš àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡ àŠàŠźàŠš àŠ­àŠŻàŠŒà§‡àŠž àŠ•àŠČ} Video {àŠȘà§àŠ°àŠ€à§àŠŻàŠŸàŠ–à§àŠŻàŠŸàŠš àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡ àŠàŠźàŠš àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČ} Group {àŠȘà§àŠ°àŠ€à§àŠŻàŠŸàŠ–à§àŠŻàŠŸàŠš àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡ àŠàŠźàŠš àŠ—à§à§°à§àŠȘ àŠ•àŠČ} other {àŠȘà§àŠ°àŠ€à§àŠŻàŠŸàŠ–à§àŠŻàŠŸàŠš àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡ àŠàŠźàŠš àŠ•àŠČ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {àŠ†àŠ°à§‹ {count,number} àŠœàŠš àŠŸàŠŸàŠ‡àŠȘ àŠ•àŠ°àŠ›à§‡àŠšà„€} other {àŠ†àŠ°à§‹ {count,number} àŠœàŠš àŠŸàŠŸàŠ‡àŠȘ àŠ•àŠ°àŠ›à§‡àŠšà„€}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àŠšàŠ€à§àŠš àŠ•àŠż", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àŠ›à§‹àŠŸ àŠ›à§‹àŠŸ àŠ•àŠżàŠ›à§ àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠš, àŠŹàŠŸàŠ— àŠžàŠ‚àŠ¶à§‹àŠ§àŠš àŠàŠŹàŠ‚ àŠȘàŠŸàŠ°àŠ«àŠ°à§àŠźà§‡àŠšà§àŠž àŠžàŠźà§ƒàŠŠà§àŠ§ àŠ•àŠ°àŠŸ àŠčà§Ÿà§‡àŠ›à§‡à„€ Signal àŠŹà§àŠŻàŠŹàŠčàŠŸàŠ° àŠ•àŠ°àŠŸàŠ° àŠœàŠšà§àŠŻ àŠ§àŠšà§àŠŻàŠŹàŠŸàŠŠ!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àŠàŠ‡ àŠ†àŠȘàŠĄà§‡àŠŸà§‡ àŠ­àŠŻàŠŒà§‡àŠž àŠ“ àŠ­àŠżàŠĄàŠżàŠ“ àŠ•àŠČà§‡àŠ° àŠœàŠšà§àŠŻ àŠ•àŠżàŠ›à§ àŠ‰àŠšà§àŠšàŠ€àŠż àŠàŠŹàŠ‚ àŠ•àŠżàŠ›à§ àŠ›à§‹àŠŸ àŠĄàŠ•à§àŠźà§‡àŠšà§àŠŸà§‡àŠ¶àŠš àŠ†àŠȘàŠĄà§‡àŠŸ àŠ…àŠšà§àŠ€àŠ°à§àŠ­à§àŠ•à§àŠ€ àŠ°àŠŻàŠŒà§‡àŠ›à§‡ (àŠ§àŠšà§àŠŻàŠŹàŠŸàŠŠ, {linkToGithub}!)à„€" + "icu:WhatsNew__v6.39--0": { + "messageformat": "àŠàŠ–àŠš àŠ†àŠȘàŠšàŠż àŠ†àŠȘàŠšàŠŸàŠ° àŠžàŠżàŠžà§àŠŸà§‡àŠź àŠžà§‡àŠŸàŠżàŠ‚àŠž àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠš àŠšàŠŸ àŠ•àŠ°à§‡àŠ‡ Signal-àŠ àŠ†àŠȘàŠšàŠŸàŠ° àŠšàŠżàŠ°à§àŠŹàŠŸàŠšàŠżàŠ€ àŠ­àŠŸàŠ·àŠŸ àŠȘàŠ°àŠżàŠŹàŠ°à§àŠ€àŠš àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠš (Signal àŠžà§‡àŠŸàŠżàŠ‚àŠž > àŠ…àŠŹà§ŸàŠŹ > àŠ­àŠŸàŠ·àŠŸ)à„€" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àŠ†àŠźàŠ°àŠŸ àŠ•àŠżàŠ›à§ àŠ—à§àŠ°à§àŠȘ àŠšà§‹àŠŸàŠżàŠ«àŠżàŠ•à§‡àŠ¶àŠš àŠ†àŠ‡àŠ•àŠš àŠ†àŠȘàŠĄà§‡àŠŸ àŠ•àŠ°à§‡àŠ›àŠżà„€" + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOS àŠĄàŠżàŠ­àŠŸàŠ‡àŠž àŠ„à§‡àŠ•à§‡ àŠ•àŠ–àŠšà§‹ àŠ•àŠ–àŠšà§‹ àŠ•àŠČ àŠČàŠŹàŠżàŠ€à§‡ àŠŻà§‹àŠ— àŠŠà§‡àŠ“àŠŻàŠŒàŠŸàŠ° àŠȘàŠ° àŠ•àŠżàŠ›à§àŠŸàŠŸ àŠŠà§‡àŠ°àŠż àŠčàŠ“à§ŸàŠŸàŠ° àŠŻà§‡ àŠžàŠźàŠžà§àŠŻàŠŸàŠŸàŠż àŠŠà§‡àŠ–àŠŸ àŠŠàŠżàŠ€à§‹ àŠ€àŠŸ àŠ†àŠźàŠ°àŠŸ àŠ àŠżàŠ• àŠ•àŠ°à§‡àŠ›àŠżà„€" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àŠŻàŠ–àŠš àŠ•à§‡àŠ‰ àŠ•à§‹àŠšà§‹ àŠ—à§àŠ°à§àŠȘ àŠ•àŠČে àŠŻà§‹àŠ— àŠŠà§‡àŠš àŠŹàŠŸ àŠŹà§‡àŠ°àŠżà§Ÿà§‡ àŠŻàŠŸàŠš àŠ€àŠ–àŠš àŠ†àŠźàŠ°àŠŸ àŠ­àŠżàŠĄàŠżàŠ“ àŠŸàŠŸàŠ‡àŠČàŠžà§‡àŠ° àŠœàŠšà§àŠŻ àŠŻà§‡ àŠŸà§àŠ°àŠŸàŠšàŠœàŠżàŠ¶àŠš àŠ…à§àŠŻàŠŸàŠšàŠżàŠźà§‡àŠ¶àŠšàŠŸàŠż àŠŠà§‡àŠ–àŠŸà§Ÿ àŠ€àŠŸ àŠ àŠżàŠ• àŠ•àŠ°à§‡àŠ›àŠżà„€" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àŠàŠ–àŠš àŠ†àŠȘàŠšàŠż àŠšà§àŠŻàŠŸàŠŸ àŠžà§‡àŠŸàŠżàŠ‚àŠžà§‡ àŠŠà§àŠ°à§àŠ€ àŠ…à§àŠŻàŠŸàŠ•à§àŠžà§‡àŠž àŠ•àŠ°àŠ€à§‡ àŠŹàŠŸ àŠžà§‡àŠ‡ àŠšà§àŠŻàŠŸàŠŸ àŠ„à§‡àŠ•à§‡ àŠ•à§‹àŠšà§‹ àŠ…àŠŠà§‡àŠ–àŠŸ àŠžà§àŠŸà§‹àŠ°àŠż àŠŠà§‡àŠ–àŠ€à§‡ àŠšà§àŠŻàŠŸàŠŸ àŠ¶àŠżàŠ°à§‹àŠšàŠŸàŠźà§‡ àŠàŠ•àŠŸàŠż àŠȘà§àŠ°à§‹àŠ«àŠŸàŠ‡àŠČ àŠ›àŠŹàŠż àŠŹàŠŸ àŠ—à§àŠ°à§àŠȘ àŠ…à§àŠŻàŠŸàŠ­àŠŸàŠŸàŠŸàŠ°à§‡ àŠ•à§àŠČàŠżàŠ• àŠ•àŠ°àŠ€à§‡ àŠȘàŠŸàŠ°àŠŹà§‡àŠšà„€ àŠ§àŠšà§àŠŻàŠŹàŠŸàŠŠ, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/bs-BA/messages.json b/_locales/bs-BA/messages.json index 18f19fe46d..8d99b3a2cb 100644 --- a/_locales/bs-BA/messages.json +++ b/_locales/bs-BA/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "GreĆĄka baze podataka", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "DoĆĄlo je do greĆĄke u bazi podataka. MoĆŸete kopirati greĆĄku i kontaktirati podrĆĄku za Signal kako biste rijeĆĄili problem. Ako trebate odmah koristiti Signal, moĆŸete izbrisati svoje podatke i izvrĆĄiti ponovno pokretanje.\n\nKontaktirajte podrĆĄku tako ĆĄto ćete posjetiti: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "IzbriĆĄi sve podatke i ponovo pokreni", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "IzbriĆĄite podatke i ponovo pokrenite", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Trajno izbrisati sve podatke?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Sva vaĆĄa historija poruka i mediji će biti trajno izbrisani s ovog uređaja. Moći ćete koristiti Signal na ovom uređaju nakon ponovnog povezivanja. Ovim se neće izbrisati nikakvi podaci sa vaĆĄeg telefona.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Verzija vaĆĄe baze podataka ne odgovara ovoj verziji Signala. Provjerite otvarate li najnoviju verziju Signala na svom računaru.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Datoteka", @@ -300,6 +316,70 @@ "messageformat": "Chatovi", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "NeĆĄto nije u redu s vaĆĄim korisničkim imenom, viĆĄe nije dodijeljeno vaĆĄem računu. MoĆŸete ga pokuĆĄati ponovo postaviti ili odabrati novo.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Popravi sada", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "NeĆĄto nije u redu s vaĆĄim QR kodom i linkom za korisničko ime, viĆĄe ne vrijedi. Kreirajte novi link za dijeljenje s drugima.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Popravi sada", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "PrikaĆŸi kartice", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Sakrij kartice", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Dogodila se greĆĄka", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} nepročitano", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Označeno kao nepročitano", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chatovi", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Pozivi", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Priče", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "PodeĆĄavanja", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "AĆŸuriraj Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Natrag", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ovi chatovi su arhivirani i pojavljivat će se samo u Pristigloj poĆĄti ako primite nove poruke.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Svakako nazovi", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Svejedno se pridruĆŸi", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Nastavite poziv", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Sigurnosni brojevi se aĆŸuriraju.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Saznajte viĆĄe", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Prethodni sigurnosni broj", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Sljedeći sigurnosni broj", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Verzija sigurnosnog broja, {index,number} od {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Označi kao provjereno", @@ -663,33 +747,41 @@ "messageformat": "Ukloni iz provjerenih", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Za potvrdu sveobuhvatnog ĆĄifriranja sa {name}, uporedite gore navedene brojeve sa njihovim uređajem. Korisnik također moĆŸe skenirati vaĆĄ kod svojim uređajem.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Saznajte viĆĄe", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Da potvrdite sveobuhvatno ĆĄifriranje sa {name}, uparite gornju karticu u boji s uređajem te osobe i uporedite brojeve. Ako se ne poklapaju, pokuĆĄajte s drugim parom sigurnosnih brojeva. Samo jedan par se treba podudarati.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Za potvrdu sveobuhvatnog ĆĄifriranja sa {name}, uporedite gore navedene brojeve sa njihovim uređajem. Korisnik također moĆŸe skenirati vaĆĄ kod svojim uređajem.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Promjene sigurnosnih brojeva", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Sigurnosni brojevi se aĆŸuriraju tokom prelaznog perioda kako bi se omogućile nadolazeće funkcije privatnosti u Signalu.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Da potvrdite sigurnosne brojeve, uparite karticu u boji sa uređajem vaĆĄeg kontakta. Ako se ne poklapaju, pokuĆĄajte s drugim parom sigurnosnih brojeva. Samo jedan par se treba podudarati.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Trebate li pomoć?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Razumijem", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Sa ovom osobom će se kreirati sigurnosni broj nakon ĆĄto s njom razmijenite poruke.", @@ -1267,10 +1359,6 @@ "messageformat": "PrikaĆŸ nedavni medijski sadrĆŸaj", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Da potvrdite sigurnost sveobuhvatnog ĆĄifriranja s kontaktom {name}, uporedite navedene brojeve s uređajem kontakta. Korisnik također moĆŸe skenirati QR kȏd iznad.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "You haven't exchanged any messages with this contact yet. Your safety number with them will be available after the first message." }, @@ -1334,17 +1422,17 @@ "messageformat": "Informacije", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "IzbriĆĄi", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "IzbriĆĄi poruku", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Izbrisati chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Izbrisati poruku?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Chat je izbrisan s ovog uređaja.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Poruke u ovom chatu će biti izbrisane s ovog uređaja. I dalje moĆŸete traĆŸiti ovaj chat nakon ĆĄto izbriĆĄete poruke.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Napusti grupu", @@ -1438,6 +1526,14 @@ "messageformat": "VaĆĄa historija poruka za oba chata je spojena ovdje.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pripada korisniku/ci {conversationTitle}. Oboje ste članovi grupe {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pripada korisniku/ci {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Sličica slike iz citirane poruke", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Pozovi ponovo", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Nazovi", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "PridruĆŸi se pozivu", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon je isključen zbog duĆŸine poziva", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Obavijesti o pozivima", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Poziv je popunjen", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Pristupi", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Započni", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Poziv je pun", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera je onemogućena", @@ -1621,10 +1725,6 @@ "messageformat": "Uključite kameru", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Isključi zvuk", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon je onemogućen", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Uključit mikrofon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Dijeli", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Prezentiranje je onemogućeno", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Prestanite prezentirati", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Zvoni", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupa je prevelika za zazvoniti učesnicima.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Omogućite zvono", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Isključi zvono", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Uključite zvono", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ViĆĄe opcija", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Vi", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "VaĆĄa kamera je isključena", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Vidi Sigurnosni broj", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Poruka", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Vidi Sigurnosni broj", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Dohvatanje broja telefona nije uspjelo. Provjerite vezu i pokuĆĄajte ponovo.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Izmjene se mogu primijeniti samo u roku od 3 sata od trenutka kada ste poslali ovu poruku.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Izmjene se mogu primijeniti samo u roku od 24 sata od trenutka kada ste poslali ovu poruku.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ova je poruka izbrisana.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Prilog je prevelik za prikaz.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Neki prilozi su preveliki za prikaz.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Dohvatanje detalja o donaciji nije uspjelo", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Samo Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Uređivanje poruka je dostupno samo korisnicima Signala beta. Ako uredite poruku, bit će vidljiva samo osobama koje koriste najnoviju verziju Signala beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Uredi poruku", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Ako uredite poruku, bit će vidljiva samo osobama koje koriste najnovije verzije Signala. Moći će vidjeti da ste uredili poruku.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Dolazni video poziv
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Odlazni glasovni poziv", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Odlazni video poziv", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} vas poziva", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Ponovno povezivanje
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} osoba} few {{count,number} osobe} many {{count,number} osoba} other {{count,number} osoba}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio poziv", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Kraj", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Napusti", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon je isključen", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon je uključen", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zvono je uključeno", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zvono je isključeno", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "PodeĆĄavanja", @@ -3468,13 +3668,25 @@ "messageformat": "Poziv na cijelom ekranu", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Pređi na prikaz mreĆŸe", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Promijeni pregled", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Pređi na prikaz govornika", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Sličice", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Prikaz bočne trake", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Prikaz govornika", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Prikaz je aĆŸuriran", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ZavrĆĄi poziv", @@ -3576,6 +3788,14 @@ "messageformat": "Uredu", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Nije moguće urediti poruku", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Samo {max,number} uređivanja se moĆŸe primijeniti na ovu poruku.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Ćœao nam je, taj sgnl:// link nije imao smisla!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Korisničko ime", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "NeĆĄto nije u redu s vaĆĄim korisničkim imenom, viĆĄe nije dodijeljeno vaĆĄem računu.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Brisanje korisničkog imena", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Kreirajte korisničko ime", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kȏd ili poveznica", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Korisničko ime treba resetirati", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Link korisničkog imena treba resetirati", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Podijelite korisničko ime", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Brisanje korisničkog imena", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Na ovaj način ćete ukloniti korisničko ime i omogućiti drugim korisnicima da ga preuzmu. Jeste li sigurni?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ovim će se ukloniti vaĆĄe korisničko ime i onemogućiti vaĆĄ QR kȏd i poveznica. Korisničko ime “{username}” će biti dostupno drugima ga uzmu za sebe. Jeste li sigurni?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ViĆĄe nećete moći dijeliti niti pregledati priče. AĆŸuriranja priča koja ste nedavno podijelili će se također izbrisati.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Jezik", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Jezik", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistemski jezik", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "TraĆŸi jezike", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nema rezultata za “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Podesi", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Ponovo pokrenite Signal za primjenu", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Da biste promijenili jezik, aplikacija se mora ponovo pokrenuti.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ponovo pokreni", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Dostupno je aĆŸuriranje na verziju {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "DoĆĄlo je do greĆĄke prilikom pohranjivanja vaĆĄih postavki. PokuĆĄajte ponovo.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Poruka", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ViĆĄe stilova", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "PoniĆĄti", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Uredu", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Boja poveznice za korisničko ime, {index,number} od {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Ako resetujete QR kȏd, vaĆĄ postojeći QR kȏd i poveznica viĆĄe neće funkcionirati.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "PoniĆĄtavanje linka...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kod i link nisu postavljeni. Provjerite mreĆŸnu vezu i pokuĆĄajte ponovo.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Postavite svoje korisničko ime za Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "uređeno", + "messageformat": "Uređeno", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "PoĆĄalji ponovo", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ViĆĄe radnji", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Pozivi", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Novi poziv", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Novi poziv", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ViĆĄe radnji", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "ObriĆĄi historiju poziva", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ObriĆĄi historiju poziva", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Ovo će trajno izbrisati svu historiju poziva", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Ukloni", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Historija poziva je obrisana", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Kliknite da vidite ili započnete poziv", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "TraĆŸi", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtriraj prema propuĆĄtenom pozivu", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Zamijeni", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nema nedavnih poziva. Započnite pozivom prijatelja.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nema rezultata za “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Dolazni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Odlazni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "PropuĆĄteni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Grupni poziv", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nema nedavnih razgovora.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nema rezultata za “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Odlazni glasovni poziv} other {Dolazni glasovni poziv}}} Video {{direction, select, Outgoing {Odlazni video poziv} other {Dolazni video poziv}}} Group {{direction, select, Outgoing {Odlazni grupni poziv} other {Dolazni grupni poziv}}} other {{direction, select, Outgoing {Odlazni poziv} other {Dolazni poziv}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {PropuĆĄteni glasovni poziv} Video {PropuĆĄten videopoziv} Group {PropuĆĄten grupni poziv} other {PropuĆĄten poziv}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {PropuĆĄteni glasovni poziv} Video {Neodgovoreni video poziv} Group {PropuĆĄten grupni poziv} other {Neodgovoren poziv}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Odbijen poziv} Video {Odbijen video poziv} Group {Odbijen grupni poziv} other {Odbijen poziv}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} druga osoba trenutno piĆĄe} few {{count,number} druge osobe trenutno piĆĄu} many {{count,number} drugih osoba trenutno piĆĄe} other {{count,number} drugih osoba trenutno piĆĄe}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Ć ta je novo", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Mala podeĆĄavanja, otklanjanje greĆĄaka i poboljĆĄanja performansi. Hvala vam ĆĄto koristite Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ovo aĆŸuriranje uključuje nekoliko poboljĆĄanja za glasovne i video pozive te neka manja aĆŸuriranja dokumentacije (hvala, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Sada moĆŸete promijeniti odabrani jezik u Signalu bez promjene postavki sistema (Postavke Signala > Izgled > Jezik)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "AĆŸurirali smo neke ikone grupnih obavijesti." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Popravili smo kratku odgodu koja se ponekad događala na macOS-u nakon pridruĆŸivanja pozivu." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Popravili smo animaciju prijelaza za videopločice kada se netko pridruĆŸi ili napusti grupni poziv." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Sada moĆŸete kliknuti profilnu sliku ili grupni avatar u zaglavlju chata kako biste brzo pristupili postavkama chata ili pregledali sve neviđene priče iz tog chata. Hvala, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ca/messages.json b/_locales/ca/messages.json index 0021702a16..3d72c7815b 100644 --- a/_locales/ca/messages.json +++ b/_locales/ca/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Error de la base de dades", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "S'ha produĂŻt un error de la base de dades. Pots copiar l'error i posar-te en contacte amb el servei d'assistĂšncia de Signal per ajudar-te a solucionar el problema. Si necessites fer servir Signal immediatament, pots eliminar les teves dades i reiniciar-lo.\n\nPosa't en contacte amb el servei d'assistĂšncia a travĂ©s de: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Suprimeix-ne totes les dades i reinicia'l", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Eliminar les dades i reiniciar", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Vols eliminar totes les dades permanentment?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Tot el teu historial de missatges i arxius multimĂšdia s'eliminaran permanentment d'aquest dispositiu. PodrĂ s utilitzar Signal en aquest dispositiu desprĂ©s de tornar-lo a enllaçar. AixĂČ no eliminarĂ  cap dada del teu telĂšfon.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "La versiĂł de la teva base de dades no coincideix amb aquesta versiĂł de Signal. Assegura't d'estar obrint la versiĂł mĂ©s recent de Signal al teu ordinador.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fitxer", @@ -300,6 +316,70 @@ "messageformat": "Xats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "S'ha produĂŻt un error amb el teu Ă lies, ja no estĂ  assignat al teu compte. Pots provar de configurar-lo de nou o triar-ne un de diferent.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Reparar-ho ara", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "S'ha produĂŻt un error amb el codi QR i enllaç del teu nom d'usuari, ja no Ă©s vĂ lid. Crea un nou enllaç per compartir. Crea un nou enllaç per compartir.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Reparar-ho ara", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Mostrar pestanyes", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ocultar pestanyes", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "S'ha produĂŻt un error", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} sense llegir", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marcat com a no llegit", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Xats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Trucades", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "HistĂČries", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ConfiguraciĂł", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Actualitza el Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Perfil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Enrere", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Aquests xats estan arxivats i nomĂ©s apareixeran a la bĂșstia d'entrada si s'hi reben missatges nous.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Truca-li tanmateix", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Unir-me de totes maneres", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continua la trucada", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Els nĂșmeros de seguretat s'estan actualitzant.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "MĂ©s informaciĂł", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "NĂșmero de seguretat anterior", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "NĂșmero de seguretat segĂŒent", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "VersiĂł de nĂșmero de seguretat {index,number} de {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marca com a verificat", @@ -663,33 +747,41 @@ "messageformat": "Neteja la verificaciĂł", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Per verificar el xifrat amb {name}, compara les xifres de dalt amb les del dispositiu d'aquella persona. TambĂ© poden escanejar el teu codi amb el seu dispositiu.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "MĂ©s informaciĂł", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Per verificar el xifrat amb {name}, tria mĂ©s a dalt la carta de color que coincideixi amb la del dispositiu d'aquella persona i compara les xifres. Si aquestes no coincideixen, prova un altre parell de nĂșmeros de seguretat. NomĂ©s cal que coincideixin un parell.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Per verificar el xifrat amb {name}, compara les xifres de dalt amb les del dispositiu d'aquella persona. TambĂ© poden escanejar el teu codi amb el seu dispositiu.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Canvis als nĂșmeros de seguretat", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "S'estan actualitzant els nĂșmeros de seguretat durant un perĂ­ode de transiciĂł per habilitar les prĂČximes funcions de privacitat de Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Per a verificar els nĂșmeros de seguretat, fes que la teva carta de color coincideixi amb la del dispositiu del teu contacte. Si aquestes no coincideixen, prova un altre parell de nĂșmeros de seguretat. NomĂ©s cal que coincideixin un parell.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Us cal ajuda?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Entesos", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Es crearĂ  un nĂșmero de seguretat amb aquesta persona desprĂ©s d'intercanviar missatges amb ella.", @@ -1267,10 +1359,6 @@ "messageformat": "Mostra el contingut recent", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Per a verificar la seguretat de l'encriptaciĂł d'extrem a extrem amb {name}, compareu els nĂșmeros anteriors amb el seu dispositiu. TambĂ© poden escanejar el codi QR de dalt.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Encara no heu intercanviat cap missatge amb aquest contacte. El vostre nĂșmero de seguretat amb ells estarĂ  disponible desprĂ©s del primer missatge." }, @@ -1334,17 +1422,17 @@ "messageformat": "InformaciĂł", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Suprimeix", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Eliminar missatges", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Vols eliminar el xat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Eliminar els missatges?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Aquest xat s'eliminarĂ  del dispositiu.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Els missatges d'aquest xat s'eliminaran d'aquest dispositiu. Encara podrĂ s cercar aquest xat desprĂ©s d'haver eliminat els missatges.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Sortir del grup", @@ -1438,6 +1526,14 @@ "messageformat": "El teu historial de missatges per ambdĂłs xats s'ha combinat aquĂ­.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pertany a {conversationTitle}. Tots dos sou membres de {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pertany a {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura d'una imatge d'un missatge citat", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Torna a trucar", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Inicia una trucada", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Afegeix-me a la trucada", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "S'ha silenciat el micrĂČfon a causa de la mida de la trucada.", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Notificacions de trucades", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "La trucada Ă©s plena", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "CĂ mera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Afegeix-m'hi", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Inicia", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Trucada plena", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "CĂ mera desactivada", @@ -1621,10 +1725,6 @@ "messageformat": "Activa la cĂ mera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silenciats", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "MicrĂČfon desactivat", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Activa el micrĂČfon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Comparteix-lo", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PresentaciĂł desactivada", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Interromp la presentaciĂł", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Truca", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "El grup Ă©s massa gran per a trucar als participants.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Activa la trucada", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Desactivar el so", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Activar el so", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "MĂ©s opcions", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Tu", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "La cĂ mera no estĂ  activa.", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Mostra el nĂșmero de seguretat", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Missatge", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Mostra el nĂșmero de seguretat", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "No s'ha pogut obtenir el nĂșmero de telĂšfon. Comproveu la connexiĂł i torneu-ho a provar.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Els canvis nomĂ©s es poden realitzar fins a 3 hores desprĂ©s d'enviar el missatge.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Els canvis nomĂ©s es poden realitzar fins 24 hores desprĂ©s d'enviar el missatge.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Aquest missatge s'ha suprimit.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "El fitxer adjunt Ă©s massa gran per mostrar-lo.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Alguns fitxers adjunts son massa grans per mostrar-los.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "No s'han pogut obtenir els detalls de la donaciĂł", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "NomĂ©s per a la versiĂł beta de Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "La funciĂł d'ediciĂł de missatges nomĂ©s estĂ  disponible per a les persones que tinguin la versiĂł beta de Signal. Si edites un missatge, nomĂ©s serĂ  visible per a aquelles persones que tinguin la darrera versiĂł de Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editar missatge", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Si edites un missatge, nomĂ©s serĂ  visible per a aquelles persones que tinguin les darreres versions de Signal. Podran veure que has editat un missatge.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Trucada de vĂ­deo entrant
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Trucada sortint", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Trucada de vĂ­deo sortint", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} us estĂ  trucant", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Tornant a connectar
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal: {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} persona} other {{count,number} persones}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Trucada", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Finalitza", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Surt", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "MicrĂČfon apagat", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "MicrĂČfon encĂšs", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "So activat", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "So desactivat", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ConfiguraciĂł", @@ -3468,13 +3668,25 @@ "messageformat": "Trucada a pantalla completa", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Canvia a la vista de graella", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Canviar la vista", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Canvia a la vista de qui parla", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Vista de graella", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Vista de la barra lateral", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Vista de l'orador", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Vista actualitzada", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Surt de la trucada", @@ -3576,6 +3788,14 @@ "messageformat": "D'acord", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "No es pot editar el missatge", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "NomĂ©s es poden realitzar {max,number} canvis en aquest missatge.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Perdoneu, l'enllaç sgnl:// no tenia sentit!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nom d'usuari", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "S'ha produĂŻt un error amb el teu Ă lies, ja no estĂ  assignat al teu compte.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Suprimeix el nom d'usuari", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Crea un nom d'usuari", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Codi QR o enllaç", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Cal restablir el nom d'usuari", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Cal restablir l'enllaç del nom d'usuari", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Comparteix el teu Ă lies", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Suprimeix el nom d'usuari", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "AixĂČ suprimirĂ  el vostre nom d'usuari i permetrĂ  que altres usuaris el reclamin. EstĂ s segur?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "AixĂČ eliminarĂ  el teu Ă lies i desactivarĂ  el teu codi QR i enllaç. \"{username}\" estarĂ  disponible perquĂš altres puguin utilitzar-lo. Segur que vols fer aixĂČ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Ja no podrĂ s compartir o veure histĂČries. Les histĂČries que hagis compartit recentment tambĂ© seran esborrades.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Idioma", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Idioma", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Idioma del sistema", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Cercar idiomes", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "No s'ha trobat cap resultat per a «{searchTerm}»", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Establir", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Reinicia Signal per aplicar", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Per canviar l'idioma, l'app s'ha de reiniciar.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Reiniciar", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ActualitzaciĂł a la versiĂł {version} disponible", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Hi ha hagut un error en desar la configuraciĂł. Torneu-ho a provar.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Missatge", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "MĂ©s estils", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Restableix", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Fet", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Color de l'enllaç de l'Ă lies, {index,number} de {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Si restableixes el teu codi QR, el teu codi QR i enllaç actuals deixaran de funcionar.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Restablint l'enllaç
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Codi QR i enllaç no establerts. Comprova la teva connexiĂł i torna-ho a intentar.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Configura el teu Ă lies de Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editat", + "messageformat": "Editat", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Envieu de nou", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "MĂ©s accions", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Trucades", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nova trucada", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nova trucada", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "MĂ©s accions", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Neteja l'historial de trucades", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Netejar l'historial de trucades?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "S'eliminarĂ  de manera permanent tot l'historial de trucades", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Neteja", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "S'ha buidat l'histĂČric de trucades", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Fes clic per veure o iniciar una trucada", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Cerca", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrar per perdudes", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Commuta", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "No hi ha cap trucada recent. Comença trucant a algĂș.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "No s'ha trobat cap resultat per a «{query}»", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Entrant", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Sortint", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Perduda", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Trucada de grup", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "No hi ha converses recents.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "No s'ha trobat cap resultat per a «{query}»", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Trucada sortint} other {Trucada entrant}}} Video {{direction, select, Outgoing {Trucada de vĂ­deo sortint} other {Trucada de vĂ­deo entrant}}} Group {{direction, select, Outgoing {Trucada grupal sortint} other {Trucada grupal entrant}}} other {{direction, select, Outgoing {Telefonada feta} other {Telefonada rebuda}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Trucada perduda} Video {Trucada de vĂ­deo perduda} Group {Trucada grupal perduda} other {Telefonada perduda}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Trucada sense contestar} Video {Trucada de vĂ­deo sense contestar} Group {Trucada de grup sense contestar} other {Trucada sense contestar}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Trucada de veu rebutjada} Video {Videotrucada rebutjada} Group {Trucada de grup rebutjada} other {Trucada rebutjada}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} persona mĂ©s estĂ  escrivint.} other {{count,number} persones mĂ©s estan escrivint.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "QuĂš hi ha de nou", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Petits ajustos, correccions d'errors i tasques de millora de rendiment. GrĂ cies per utilitzar Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Aquesta actualitzaciĂł inclou algunes millores per a trucades de veu i videotrucades, i algunes actualitzacions menors de la documentaciĂł (grĂ cies, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Ara pots canviar l'idioma seleccionat a Signal sense canviar els ajustos del teu sistema (Ajustos de Signal > Aparença > Idioma)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Hem modificat algunes de les icones de notificacions per a grups ." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Hem corregit un petit retard que de vegades es produĂŻa en unir-te a una sala de trucades en dispositius macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Hem arreglat l'animaciĂł de transiciĂł dels mosaics de vĂ­deo quan algĂș s'uneix o surt d'una trucada grupal." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Ara pots fer clic sobre una foto de perfil o a un avatar de grup a la capçalera del xat per accedir rĂ pidament als ajustos del xat o veure les histĂČries pendents d'aquest xat. GrĂ cies, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/cs/messages.json b/_locales/cs/messages.json index c6d7b8195b..ce82cc319c 100644 --- a/_locales/cs/messages.json +++ b/_locales/cs/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Chyba databĂĄze", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Vyskytla se chyba databĂĄze. Chybu si mĆŻĆŸete zkopĂ­rovat a obrĂĄtit se na podporu Signal, aby vĂĄm ji pomohla opravit. JestliĆŸe potƙebujete pouĆŸĂ­vat sluĆŸbu Signal ihned, mĆŻĆŸete smazat svĂĄ data a restartovat ji.\n\nPodporu kontaktujte na adrese: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Odstranit vĆĄechna data a restartovat", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Smazat data a restartovat", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Trvale smazat vĆĄechna data?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "VeĆĄkerĂĄ vaĆĄe historie zprĂĄv a mĂ©diĂ­ bude trvale z tohoto zaƙízenĂ­ odstraněna. SluĆŸbu Signal budete moct na tomto zaƙízenĂ­ pouĆŸĂ­vat po jeho opětovnĂ©m propojenĂ­. TĂ­mto postupem nedojte ke smazĂĄnĂ­ ĆŸĂĄdnĂœch dat z vaĆĄeho telefonu.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Verze vaĆĄĂ­ databĂĄze neodpovĂ­dĂĄ tĂ©to verzi aplikace Signal. Ujistěte se, ĆŸe v počítači otevĂ­rĂĄte nejnovějĆĄĂ­ verzi aplikace Signal.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Soubor", @@ -300,6 +316,70 @@ "messageformat": "Chaty", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Něco se pokazilo s vaĆĄĂ­m uĆŸivatelskĂœm jmĂ©nem. JiĆŸ nenĂ­ pƙiƙazeno k vaĆĄemu Ășčtu. MĆŻĆŸete ho zkusit nastavit znovu, nebo si zvolit novĂ©.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Opravit hned", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Něco se pokazilo s vaĆĄĂ­m QR kĂłdem a odkazem na uĆŸivatelskĂ© jmĂ©no. JiĆŸ nejsou platnĂ©. Vytvoƙte si novĂœ odkaz, kterĂœ mĆŻĆŸete sdĂ­let s ostatnĂ­mi.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Opravit hned", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Zobrazit karty", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "SkrĂœt karty", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Vyskytla se chyba", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} nepƙečtenĂœch", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Označeno jako nepƙečtenĂ©", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chaty", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "VolĂĄnĂ­", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Pƙíběhy", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "NastavenĂ­", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Aktualizovat Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Zpět", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Tyto chaty jsou archivovanĂ© a zobrazĂ­ se ve sloĆŸce pƙijatĂœch zprĂĄv pouze v pƙípadě pƙijetĂ­ novĂœch zprĂĄv.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Pƙesto zavolat", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Pƙipojit se i tak", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Pokračovat ve volĂĄnĂ­", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "BezpečnostnĂ­ čísla se aktualizujĂ­.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Zjistit vĂ­ce", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "PƙedchozĂ­ bezpečnostnĂ­ číslo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "DalĆĄĂ­ bezpečnostnĂ­ číslo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Verze bezpečnostnĂ­ho čísla, {index,number} z {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Označit jako ověƙenĂ©", @@ -663,33 +747,41 @@ "messageformat": "Vymazat ověƙenĂ­", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Chcete-li ověƙit koncovĂ© ĆĄifrovĂĄnĂ­ s uĆŸivatelem {name}, porovnejte vĂœĆĄe uvedenĂĄ čísla s jeho zaƙízenĂ­m. VĂĄĆĄ kĂłd mĆŻĆŸe takĂ© naskenovat svĂœm zaƙízenĂ­m.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Zjistit vĂ­ce", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Chcete-li ověƙit koncovĂ© ĆĄifrovĂĄnĂ­ s uĆŸivatelem {name}, pƙiƙaďte vĂœĆĄe uvedenou barevnou kartu k jejich zaƙízenĂ­ a porovnejte čísla. Pokud se čísla neshodujĂ­, zkuste druhou dvojici bezpečnostnĂ­ch čísel. MusĂ­ se shodovat pouze jedna dvojice.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Chcete-li ověƙit koncovĂ© ĆĄifrovĂĄnĂ­ s uĆŸivatelem {name}, porovnejte vĂœĆĄe uvedenĂĄ čísla s jeho zaƙízenĂ­m. VĂĄĆĄ kĂłd mĆŻĆŸe takĂ© naskenovat svĂœm zaƙízenĂ­m.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Změny u bezpečnostnĂ­ch čísel", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "BezpečnostnĂ­ čísla se po pƙechodnĂ©m obdobĂ­ aktualizujĂ­, aby bylo moĆŸnĂ© v aplikaci Signal vyuĆŸĂ­vat pƙipravovanĂ© funkce ochrany osobnĂ­ch ĂșdajĆŻ.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Chcete-li ověƙit bezpečnostnĂ­ čísla, zkontrolujte barevnou kartu se zaƙízenĂ­m svĂ©ho kontaktu. Pokud se čísla neshodujĂ­, zkuste druhou dvojici bezpečnostnĂ­ch čísel. MusĂ­ se shodovat pouze jedna dvojice.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Potƙebujete pomoc?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "RozumĂ­m", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Jakmile si s někĂœm vyměnĂ­te zprĂĄvy, bude pro danĂ©ho člověka vytvoƙeno bezpečnostnĂ­ číslo.", @@ -1267,10 +1359,6 @@ "messageformat": "Zobrazit nedĂĄvnĂĄ mĂ©dia", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Chcete-li ověƙit bezpečnost koncovĂ©ho ĆĄifrovĂĄnĂ­ s uĆŸivatelem {name}, porovnejte vĂœĆĄe uvedenĂĄ čísla s jeho zaƙízenĂ­m. MĆŻĆŸe takĂ© naskenovat vĂœĆĄe uvedenĂœ QR kĂłd.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "S tĂ­mto kontaktem jste si jeĆĄtě nevyměnili ĆŸĂĄdnĂ© zprĂĄvy. BezpečnostnĂ­ číslo k němu bude dostupnĂ© po prvnĂ­ zprĂĄvě." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Odstranit", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Odstranit zprĂĄvy", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Odstranit chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Odstranit zprĂĄvy?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Tento chat bude z tohoto zaƙízenĂ­ odstraněn.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ZprĂĄvy v tomto chatu budou z tohoto zaƙízenĂ­ odstraněny. Po odstraněnĂ­ zprĂĄv mĆŻĆŸete tento chat nadĂĄle pouĆŸĂ­vat.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Opustit skupinu", @@ -1438,6 +1526,14 @@ "messageformat": "Historie vaĆĄich zprĂĄv z obou chatĆŻ byla sloučena zde.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} patƙí k {conversationTitle}. Oba jste členovĂ© skupiny {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} patƙí k {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura obrĂĄzku z citovanĂ© zprĂĄvy", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Zavolat znovu", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ZahĂĄjit hovor", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Pƙipojit se k hovoru", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon ztlumen kvĆŻli velkĂ©mu počtu lidĂ­ v hovoru", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "OznĂĄmenĂ­ o hovorech", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Hovor je plně obsazen", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "FotoaparĂĄt", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Pƙipojit", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Začít", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Hovor plně obsazen", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera zakĂĄzĂĄna", @@ -1621,10 +1725,6 @@ "messageformat": "Zapnout kameru", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Ztlumit", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon je vypnutĂœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Zapnout mikrofon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "SdĂ­let", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Prezentace vypnuta", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Zastavit prezentaci", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "VyzvĂĄněnĂ­", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Skupina je pro volĂĄnĂ­ pƙíliĆĄ velkĂĄ", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Povolit zvoněnĂ­", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Vypnout vyzvĂĄněnĂ­", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Zapnout vyzvĂĄněnĂ­", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "VĂ­ce moĆŸnostĂ­", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Vy", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "VaĆĄe kamera je vypnutĂĄ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Zobrazit bezpečnostnĂ­ číslo", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ZprĂĄva", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Zobrazit bezpečnostnĂ­ číslo", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Nepodaƙilo se načíst telefonnĂ­ číslo. Zkontrolujte pƙipojenĂ­ a zkuste to znovu.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Úpravy lze provĂĄdět pouze do 3 hodin od odeslĂĄnĂ­ zprĂĄvy.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Úpravy lze provĂĄdět pouze do 24 hodin od odeslĂĄnĂ­ tĂ©to zprĂĄvy.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Tato zprĂĄva byla odstraněna.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Pƙíloha je pƙíliĆĄ velkĂĄ pro zobrazenĂ­.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "NěkterĂ© pƙílohy jsou pƙíliĆĄ velkĂ© pro zobrazenĂ­.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nelze načíst Ășdaje o pƙíspěvcĂ­ch", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Pouze Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Úprava zprĂĄv je dostupnĂĄ jen uĆŸivatelĆŻm verze Signal beta. Pokud zprĂĄvu upravĂ­te, zobrazĂ­ se jen lidem, kteƙí pouĆŸĂ­vajĂ­ nejnovějĆĄĂ­ verzi Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Úprava zprĂĄvy", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Pokud zprĂĄvu upravĂ­te, zobrazĂ­ se jen lidem, kteƙí pouĆŸĂ­vajĂ­ nejnovějĆĄĂ­ verzi aplikace Signal. Ti uvidĂ­, ĆŸe jste zprĂĄvu upravili.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "PƙíchozĂ­ videohovor
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "OdchozĂ­ hlasovĂœ hovor", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "OdchozĂ­ videhovor", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} vĂĄm volĂĄ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "OpětovnĂ© pƙipojovĂĄní
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal hovor trval {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} člověk} few {{count,number} lidĂ©} many {{count,number} lidĂ­} other {{count,number} lidĂ­}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "HlasovĂœ hovor", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Ukončit", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Opustit", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon vypnutĂœ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon zapnutĂœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "VyzvĂĄněnĂ­ zapnuto", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "VyzvĂĄněnĂ­ vypnuto", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "NastavenĂ­", @@ -3468,13 +3668,25 @@ "messageformat": "Hovor pƙes celou obrazovku", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Pƙepnout do zobrazenĂ­ mĆ™Ă­ĆŸky", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Změnit zobrazenĂ­", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Pƙepnout na zobrazenĂ­ mluvčího", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ZobrazenĂ­ v mĆ™Ă­ĆŸce", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ZobrazenĂ­ v postrannĂ­m panelu", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ZobrazenĂ­ ƙečnĂ­ka", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ZobrazenĂ­ aktualizovĂĄno", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Opustit hovor", @@ -3576,6 +3788,14 @@ "messageformat": "V poƙádku", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ZprĂĄvu jiĆŸ nelze upravovat", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "U tĂ©to zprĂĄvy lze pouĆŸĂ­t pouze {max,number} Ășprav.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "OmlouvĂĄme se, ale odkaz sgnl:// nedĂĄvĂĄ smysl.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "UĆŸivatelskĂ© jmĂ©no", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Něco se pokazilo s vaĆĄĂ­m uĆŸivatelskĂœm jmĂ©nem. JiĆŸ nenĂ­ pƙiƙazeno k vaĆĄemu Ășčtu.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Smazat uĆŸivatelskĂ© jmĂ©no", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Vytvoƙit uĆŸivatelskĂ© jmĂ©no", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kĂłd nebo odkaz", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "UĆŸivatelskĂ© jmĂ©no je potƙeba resetovat", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Odkaz na uĆŸivatelskĂ© jmĂ©no je potƙeba resetovat", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "SdĂ­lenĂ­ uĆŸivatelskĂ©ho jmĂ©na", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Smazat uĆŸivatelskĂ© jmĂ©no", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "TĂ­mto odstranĂ­te svĂ© uĆŸivatelskĂ© jmĂ©no a umoĆŸnĂ­te ostatnĂ­m uĆŸivatelĆŻm, aby si ho pƙivlastnili. Jste si tĂ­m jisti?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "TĂ­m odstranĂ­te svĂ© uĆŸivatelskĂ© jmĂ©no a deaktivujete svĆŻj QR kĂłd a odkaz. „{username}“ budou moci pouĆŸĂ­t ostatnĂ­. Jste si jisti?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Pƙíběhy jiĆŸ nebudete moci sdĂ­let ani zobrazovat. SmazĂĄny budou takĂ© aktualizace pƙíběhĆŻ, kterĂ© jste nedĂĄvno sdĂ­leli.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Jazyk", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Jazyk", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Jazyk systĂ©mu", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Jazyky vyhledĂĄvĂĄnĂ­", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Pro „{searchTerm}“ nebylo nic nalezeno", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Nastavit", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Pro uplatněnĂ­ změny Signal restartujte", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Pro změnu jazyka je potƙeba aplikaci restartovat.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Restartovat", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "K dispozici je aktualizace na verzi {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Pƙi uklĂĄdĂĄnĂ­ nastavenĂ­ se vyskytla chyba. Zkuste to prosĂ­m znovu.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ZprĂĄva", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "DalĆĄĂ­ styly", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Obnovit", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Hotovo", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Barva odkazu uĆŸivatelskĂ©ho jmĂ©na, {index,number} z {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Pokud zresetujete svĆŻj QR kĂłd, vĂĄĆĄ stĂĄvajĂ­cĂ­ QR kĂłd a odkaz jiĆŸ nebudou fungovat.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ResetovĂĄnĂ­ odkazu
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kĂłd a odkaz nejsou nastaveny. Zkontrolujte pƙipojenĂ­ k internetu a zkuste to znovu.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "NastavenĂ­ uĆŸivatelskĂ©ho jmĂ©na v aplikaci Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "upraveno", + "messageformat": "Upraveno", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Znovu odeslat", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "DalĆĄĂ­ akce", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "VolĂĄnĂ­", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "NovĂœ hovor", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "NovĂœ hovor", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "DalĆĄĂ­ akce", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Smazat historii hovorĆŻ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Smazat historii hovorĆŻ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "TĂ­m se trvale smaĆŸe veĆĄkerĂĄ historie hovorĆŻ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Vymazat", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Historie smazĂĄna", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "KliknutĂ­m zobrazĂ­te nebo zahĂĄjĂ­te hovor", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Hledat", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrovat podle zmeĆĄkanĂœch hovorĆŻ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Pƙepnout", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĆœĂĄdnĂ© nedĂĄvnĂ© hovory. Začněte tĂ­m, ĆŸe zavolĂĄte pƙíteli.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Pro „{query}“ nebylo nic nalezeno", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "PƙíchozĂ­", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "OdchozĂ­", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ZmeĆĄkanĂ©", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "SkupinovĂœ hovor", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĆœĂĄdnĂ© nedĂĄvnĂ© konverzace.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Pro „{query}“ nebylo nic nalezeno", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {OdchozĂ­ hlasovĂœ hovor} other {PƙíchozĂ­ hlasovĂœ hovor}}} Video {{direction, select, Outgoing {OdchozĂ­ videhovor} other {PƙíchozĂ­ videohovor}}} Group {{direction, select, Outgoing {OdchozĂ­ skupinovĂœ hovor} other {PƙíchozĂ­ skupinovĂœ hovor}}} other {{direction, select, Outgoing {OdchozĂ­ hovor} other {PƙíchozĂ­ hovor}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ZmeĆĄkanĂœ hlasovĂœ hovor} Video {ZmeĆĄkanĂœ videohovor} Group {ZmeĆĄkanĂœ skupinovĂœ hovor} other {ZmeĆĄkanĂœ hovor}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {NepƙijatĂœ hlasovĂœ hovor} Video {NepƙijatĂœ videohovor} Group {NepƙijatĂœ skupinovĂœ hovor} other {NepƙijatĂœ hovor}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {OdmĂ­tnutĂœ hlasovĂœ hovor} Video {OdmĂ­tnutĂœ videohovor} Group {OdmĂ­tnutĂœ skupinovĂœ hovor} other {OdmĂ­tnutĂœ hovor}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} dalĆĄĂ­ pĂ­ĆĄe.} few {{count,number} dalĆĄĂ­ pĂ­ĆĄou.} many {{count,number} dalĆĄĂ­ch pĂ­ĆĄe.} other {{count,number} dalĆĄĂ­ch pĂ­ĆĄe.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Co je novĂ©ho", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "DrobnĂĄ vylepĆĄenĂ­, opravy chyb a zvĂœĆĄenĂ­ vĂœkonu. Děkujeme, ĆŸe pouĆŸĂ­vĂĄte Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Tato aktualizace obsahuje několik vylepĆĄenĂ­ pro hlasovĂ© a video hovory a několik drobnĂœch doplněnĂ­ dokumentace ({linkToGithub} – děkujeme!)" + "icu:WhatsNew__v6.39--0": { + "messageformat": "VybranĂœ jazyk mĆŻĆŸete nynĂ­ změnit v aplikaci Signal, aniĆŸ byste museli měnit nastavenĂ­ systĂ©mu (NastavenĂ­ Signal > Vzhled > Jazyk)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Upravili jsme některĂ© ikony skupinovĂœch oznĂĄmenĂ­." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Opravili jsme krĂĄtkĂ© zpoĆŸděnĂ­, ke kterĂ©mu občas dochĂĄzelo na zaƙízenĂ­ch macOS po pƙipojenĂ­ do rozhranĂ­ skupinovĂ©ho hovoru." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Opravili jsme pƙechodovou animaci u video dlaĆŸdic, kdyĆŸ se někdo pƙipojĂ­ ke skupinovĂ©mu hovoru někdo jej opustĂ­." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Teď mĆŻĆŸete kliknutĂ­m na profilovou fotku nebo avatar skupiny v zĂĄhlavĂ­ chatu rychle pƙistupovat k nastavenĂ­ chatu nebo zobrazit vĆĄechny dosud neprohlĂ©dnutĂ© pƙíběhy z tohoto chatu. Děkujeme, uĆŸivateli {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/da/messages.json b/_locales/da/messages.json index c1b5c762f9..9cd17a946d 100644 --- a/_locales/da/messages.json +++ b/_locales/da/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Databasefejl", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Der opstod en databasefejl. Du kan kopiere fejlen og kontakte Signals support for at fĂ„ hjĂŠlp til at lĂžse problemet. Hvis du skal bruge Signal med det samme, kan du slette dine data og genstarte.\n\nKontakt supporten ved at gĂ„ til: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Slet alle data og genstart", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Slet data og genstart", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Slet alle data permanent?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Din samlede beskedhistorik og dine medier slettes permanent fra denne enhed. Du vil kunne bruge Signal pĂ„ denne enhed, nĂ„r du har genoprettet forbindelsen. Dette sletter ikke data fra din telefon.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Din version af databasen stemmer ikke overens med denne version af Signal. SĂžrg for, at du Ă„bner den nyeste version af Signal pĂ„ din computer.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fil", @@ -300,6 +316,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Noget gik galt med dit brugernavn. Det er ikke lĂŠngere tildelt din konto. Du kan prĂžve at indstille det igen eller vĂŠlge et nyt.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "FĂ„ hjĂŠlp nu", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Noget gik galt med din QR-kode og dit link til dit brugernavn, det er ikke lĂŠngere gyldigt. Opret et nyt link for at dele det med andre.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "FĂ„ hjĂŠlp nu", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Vis faner", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Skjul faner", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Der opstod en fejl", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ulĂŠst", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Markeret som ulĂŠst", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Opkald", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Historier", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Indstillinger", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "OpdatĂ©r Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Tilbage", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Disse chats arkiveres og vises kun i indbakken, hvis der modtages nye beskeder.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ring alligevel", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Deltag alligevel", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "FortsĂŠt opkald", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Sikkerhedsnumrene opdateres.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "LĂŠs mere", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Forrige sikkerhedsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "NĂŠste sikkerhedsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Sikkerhedsnummerversion, {index,number} af {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "MarkĂ©r som bekrĂŠftet", @@ -663,33 +747,41 @@ "messageformat": "Fjern verifikation", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "For at verificere E2E-krypteringen med {name}, skal du sammenligne ovenstĂ„ende tal med vedkommendes enhed. De kan ogsĂ„ scanne koden pĂ„ vedkommendes enhed.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "LĂŠs mere", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Hvis du vil verificere din E2E-kryptering med {name}, skal du matche farvekortet ovenfor med deres enhed og sammenligne tallene. Hvis de ikke matcher, skal du swipe for at prĂžve det andet sĂŠt sikkerhedsnumre. Det er kun Ă©t sĂŠt, der skal matche.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "For at verificere E2E-krypteringen med {name}, skal du sammenligne ovenstĂ„ende tal med vedkommendes enhed. De kan ogsĂ„ scanne koden pĂ„ vedkommendes enhed.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Ændring af sikkerhedsnumre", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Sikkerhedsnumre opdateres i en overgangsperiode for at muliggĂžre kommende privatlivsfunktioner i Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "For at verificere sikkerhedsnumrene, skal du matche farvekortet med din kontakts enhed. Hvis de ikke matcher, skal du swipe for at prĂžve det andet sĂŠt sikkerhedsnumre. Det er kun Ă©t sĂŠt, der skal matche.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Brug for hjĂŠlp?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ForstĂ„et", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Der oprettes et sikkerhedsnummer med denne person, nĂ„r du har udvekslet beskeder med dem.", @@ -1267,10 +1359,6 @@ "messageformat": "Vis seneste medier", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "For at verificere sikkerheden af din E2E-kryptering med {name}, skal du sammenligne ovenstĂ„ende tal med deres enhed. De kan ogsĂ„ scanne ovenstĂ„ende QR-kode.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Du har ikke udvekslet nogen beskeder med kontaktpersonen endnu. Dit sikkerhedsnummer med vedkommende vil vĂŠre tilgĂŠngeligt efter den fĂžrste besked." }, @@ -1334,17 +1422,17 @@ "messageformat": "Information", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Slet", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Slet beskeder", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Slet chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Slet beskeder?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Chatten vil blive slettet fra denne enhed.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Beskeder i denne chat slettes fra denne enhed. Du kan stadig sĂžge efter denne chat, nĂ„r du har slettet beskeder.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Forlad gruppe", @@ -1438,6 +1526,14 @@ "messageformat": "Din beskedhistorik for begge chats er slĂ„et sammen her.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} tilhĂžrer {conversationTitle}. I er begge medlemmer af {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} tilhĂžrer {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniature af billede fra citeret besked", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ring igen", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Foretag opkald", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Deltag i opkald", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon slĂ„et fra pĂ„ grund af opkaldets stĂžrrelse", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Opkaldsnotifikationer", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Opkaldet er fuldt", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Deltag", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Start", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Opkaldet er fuldt", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera dĂ©aktiveret", @@ -1621,10 +1725,6 @@ "messageformat": "AktivĂ©r kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Ignorer", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon dĂ©aktiveret", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "SlĂ„ mikrofon til", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Del", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PrĂŠsentation deaktiveret", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Stop prĂŠsentation", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ring", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Gruppe er for stor til at ringe til alle deltagerne.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Aktiver ringetone", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "SlĂ„ opringning fra", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "SlĂ„ opringning til", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Flere muligheder", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Dig", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Dit kamera er slĂ„et fra", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Vis sikkerhedsnummer", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Send besked", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Vis sikkerhedsnummer", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Det lykkedes ikke at hente telefonnummer. Kontroller din forbindelse, og prĂžv igen.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Ændringer kan kun foretages inden for 3 timer efter at du har sendt denne besked.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Ændringer kan kun foretages indenfor 24 timer efter at du har sendt denne besked.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Beskeden blev slettet.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Den vedhĂŠftede fil er for stor til at vise.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Nogle vedhĂŠftede filer er for store til at blive vist.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Kunne ikke hente donationsoplysninger", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Kun Signal Beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Redigering af beskeder er kun tilgĂŠngelig for Signal Beta-brugere. Hvis du redigerer en besked, vil den kun vĂŠre synlig for folk, der er pĂ„ den nyeste version af Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Rediger besked", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Hvis du redigerer en besked, vil den kun vĂŠre synlig for folk, der bruger de nyeste versioner af Signal. De vil kunne se, at du har redigeret en besked.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "IndgĂ„ende videoopkald
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "UdgĂ„ende stemmeopkald", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "UdgĂ„ende videoopkald", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ringer til dig", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Forbinder igen
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} person} other {{count,number} personer}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Lydopkald", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Afslut", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Forlad", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon slĂ„et fra", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon slĂ„et til", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Opringning slĂ„et til", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Opringning slĂ„et fra", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Indstillinger", @@ -3468,13 +3668,25 @@ "messageformat": "FuldskĂŠrmsopkald", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Skift til gittervisning", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Skift visning", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Skift til hĂžjttalervisning", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Gittervisning", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "SidebjĂŠlkevisning", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Talervisning", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Se opdateret", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Forlad opkald", @@ -3576,6 +3788,14 @@ "messageformat": "Okay", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Kan ikke redigere besked", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Denne besked kan kun redigeres {max,number} gange.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Beklager, det sgnl://-link gav ikke mening!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Brugernavn", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Noget gik galt med dit brugernavn. Det er ikke lĂŠngere tildelt din konto.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Slet brugernavn", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Opret et brugernavn", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-kode eller link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Brugernavnet skal nulstilles", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Link til brugernavnet skal nulstilles", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Del dit brugernavn", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Slet brugernavn", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Dette vil fjerne dit brugernavn, hvorefter andre brugere kan gĂžre krav pĂ„ det. Er du sikker?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Dette vil fjerne dit brugernavn og deaktivere din QR-kode og dit link. Andre vil dermed have mulighed for at bruge \"{username}\". Er du sikker?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Du vil ikke lĂŠngere kunne dele eller se historier. Historieopdateringer, du for nylig har delt, slettes ogsĂ„.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Sprog", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Sprog", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Systemsprog", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "SĂžg efter sprog", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Ingen resultater for \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Indstil", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Genstart Signal for at anvende", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Appen skal genstartes for at skifte sprog.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Genstart", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Opdatering til version {version} tilgĂŠngelig", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Der opstod en fejl, da du gemte dine indstillinger. PrĂžv venligst igen.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Besked", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Flere looks", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Nulstil", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "UdfĂžrt", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Brugernavnets linkfarve, {index,number} af {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Hvis du nulstiller din QR-kode, vil din eksisterende QR-kode og dit link ikke lĂŠngere fungere.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Nulstiller link...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-kode og link er ikke indstillet. Tjek din netvĂŠrksforbindelse, og prĂžv igen.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Angiv dit Signal-brugernavn", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "redigeret", + "messageformat": "Redigeret", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Send igen", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Flere handlinger", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Opkald", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nyt opkald", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nyt opkald", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Flere handlinger", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Ryd opkaldshistorik", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Vil du rydde opkaldshistorik?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Dette vil permanent slette al opkaldshistorik", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Fjern", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Opkaldshistorik slettet", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klik for at se eller starte et opkald", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "SĂžg", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "FiltrĂ©r efter ubesvaret", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Skift", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ingen nye opkald. Kom i gang ved at ringe til en ven.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Ingen resultater for \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Indkommende", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "UdgĂ„ende", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Ubesvaret", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Gruppeopkald", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ingen nylige samtaler.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Ingen resultater for \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {UdgĂ„ende stemmeopkald} other {IndgĂ„ende stemmeopkald}}} Video {{direction, select, Outgoing {UdgĂ„ende videoopkald} other {IndgĂ„ende videoopkald}}} Group {{direction, select, Outgoing {UdgĂ„ende gruppeopkald} other {IndgĂ„ende gruppeopkald}}} other {{direction, select, Outgoing {UdgĂ„ende opkald} other {Indkommende opkald}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Ubesvaret stemmeopkald} Video {Ubesvaret videoopkald} Group {Ubesvaret gruppeopkald} other {Ubesvaret opkald}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Ubesvaret stemmeopkald} Video {Ubesvaret videoopkald} Group {Ubesvaret gruppeopkald} other {Ubesvaret opkald}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Afvist taleopkald} Video {Afvist videoopkald} Group {Afvist gruppeopkald} other {Afvist opkald}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} anden skriver.} other {{count,number} andre skriver.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Nyheder", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "SmĂ„ tweaks, rettelser og forbedringer af appens prĂŠstation. Tak fordi du bruger Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Denne opdatering byder pĂ„ forbedrede tale- og videoopkald og en rĂŠkke mindre dokumentationsopdateringer (tak, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Nu kan du ĂŠndre dit valgte sprog i Signal uden at ĂŠndre dine systemindstillinger (Signal-indstillinger > Udseende > Sprog)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Vi har ĂŠndret de notifikationsikoner, der vises ved gruppeopdateringer, f.eks. nĂ„r en ny person tilmelder sig en gruppe. Disse ikoner hjĂŠlper med at forbedre lĂŠsbarheden, isĂŠr hvis du lever i mĂžrket i det mĂžrke tema. De tidligere ikoner blev blot mĂžrket. De nye ikoner er designet sĂ„dan, og formet efter det." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Vi har rettet en kort forsinkelse, der nogle gange opstod, nĂ„r man tilsluttede sig en opkaldslobby pĂ„ macOS-enheder, hvilket burde fjerne mindst Ă©n undskyldning for at komme et halvt sekund for sent til mĂždet." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Vi har rettet overgangsanimationen for videofliser, nĂ„r nogen slutter sig til eller forlader et gruppeopkald. NĂ„r du ser en vens ansigt glide ind i billedet, er det en social bevĂŠgelse." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Nu kan du klikke pĂ„ et profilbillede eller gruppens avatar i chatoverskriften for hurtigt at Ă„bne indstillingerne eller se historier, som du ikke har set endnu. Tak, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/de/messages.json b/_locales/de/messages.json index b0ab6150ab..7d84b482cf 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Datenbankfehler", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ein Datenbank-Fehler ist aufgetreten. Du kannst den Fehler kopieren und den Signal-Support kontaktieren, um dabei zu helfen, dieses Problem zu beheben. Wenn du Signal sofort verwenden möchtest, kannst du deine Daten löschen und neu starten.\n\nKontaktiere den Support unter: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Alle Daten löschen und neu starten", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Daten löschen und neu starten", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Alle Daten unwiderruflich löschen?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Dein Nachrichtenverlauf und deine Medieninhalte werden dauerhaft von diesem GerĂ€t gelöscht. Du kannst Signal auf diesem GerĂ€t verwenden, nachdem du es neu gekoppelt hast. Dabei werden keine Daten von deinem Telefon gelöscht.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Die Version in deiner Datenbank stimmt nicht mit dieser Version von Signal ĂŒberein. ÜberprĂŒfe, ob du die neueste Version von Signal auf deinem Computer geöffnet hast.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Datei", @@ -300,6 +316,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Mit deinem Nutzernamen ist etwas schief gelaufen, er ist deinem Konto nicht mehr zugeordnet. Du kannst versuchen, ihn erneut einzugeben oder einen neuen zu wĂ€hlen.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Jetzt beheben", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Mit dem QR-Code und Link deines Nutzernamens ist etwas schief gelaufen, sie sind nicht mehr gĂŒltig. Erstelle einen neuen Link, um ihn mit anderen zu teilen.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Jetzt beheben", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Tabs anzeigen", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Tabs verbergen", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ein Fehler ist aufgetreten", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ungelesen", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Als ungelesen markiert", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Anrufe", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Storys", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Einstellungen", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal aktualisieren", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ZurĂŒck", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Diese Chats werden archiviert und erscheinen nur dann im Eingang, wenn neue Nachrichten eingegangen sind.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Trotzdem anrufen", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Trotzdem beitreten", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Anruf fortsetzen", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Die Sicherheitsnummern werden aktualisiert.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Mehr erfahren", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Vorherige Sicherheitsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "NĂ€chste Sicherheitsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Sicherheitsnummer-Version {index,number} von {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Als verifiziert markieren", @@ -663,33 +747,41 @@ "messageformat": "Verifikation entfernen", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Um die Ende-zu-Ende-VerschlĂŒsselung mit {name} zu verifizieren, vergleiche die Nummern mit seinem/ihrem GerĂ€t. Er/sie kann deinen Code auch mit seinem/ihrem GerĂ€t scannen.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Mehr erfahren", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Um die Ende-zu-Ende-VerschlĂŒsselung mit {name} zu verifizieren, ordne die obige Farbkarte seinem/ihrem GerĂ€t zu und vergleiche die Nummern. Wenn diese nicht ĂŒbereinstimmen, versuche es mit den anderen Sicherheitsnummern. Es reicht, wenn ein Nummernpaar zusammenpasst.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Um die Ende-zu-Ende-VerschlĂŒsselung mit {name} zu verifizieren, vergleiche die Nummern mit seinem/ihrem GerĂ€t. Er/sie kann deinen Code auch mit seinem/ihrem GerĂ€t scannen.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Änderungen an den Sicherheitsnummern", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Die Sicherheitsnummern werden wĂ€hrend eines Ladevorgangs aktualisiert, um neue Datenschutzfunktionen in Signal zu aktivieren.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Um die Sicherheitsnummern zu verifizieren, ordne die Farbkarte dem GerĂ€t deines Kontaktes zu. Wenn die Nummern nicht ĂŒbereinstimmen, versuche es mit den anderen Sicherheitsnummern. Es reicht, wenn ein Nummernpaar zusammenpasst.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Hilfe benötigt?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Verstanden", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Nachdem du mit dieser Person Nachrichten ausgetauscht hast, wird eine Sicherheitsnummer erstellt.", @@ -1267,10 +1359,6 @@ "messageformat": "Letzte Medieninhalte anzeigen", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Um die Ende-zu-Ende-VerschlĂŒsselung mit {name} zu verifizieren, vergleiche die Nummern mit seinem/ihrem GerĂ€t. Er/sie kann auch den obigen QR-Code scannen.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Du hast bisher noch keine Nachrichten mit diesem Kontakt ausgetauscht. Eure gemeinsame Sicherheitsnummer wird nach der ersten Nachricht verfĂŒgbar sein." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Löschen", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Nachrichten löschen", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Chat löschen?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Nachrichten löschen?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Dieser Chat wird von diesem GerĂ€t gelöscht.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Nachrichten in diesem Chat werden von diesem GerĂ€t gelöscht. Du kannst nach dem Löschen von Nachrichten weiterhin nach diesem Chat suchen.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Gruppe verlassen", @@ -1438,6 +1526,14 @@ "messageformat": "Dein Nachrichtenverlauf fĂŒr beide Chats wurde hier zusammengefĂŒhrt.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} gehört zu {conversationTitle}. Ihr seid beide Mitglieder von {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} gehört zu {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniaturbild aus zitierter Nachricht", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Erneut anrufen", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Anruf starten", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Anruf beitreten", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon stummgeschaltet aufgrund der Anzahl der Anrufteilnehmer", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Benachrichtigungen fĂŒr Anrufe", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Anruf ist voll", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Beitreten", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Starten", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Anruf voll", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera deaktiviert", @@ -1621,10 +1725,6 @@ "messageformat": "Kamera einschalten", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Stummschalten", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon deaktiviert", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Mikrofon einschalten", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Teilen", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PrĂ€sentationen deaktiviert", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "PrĂ€sentation stoppen", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Klingeln", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Gruppe ist zu groß, um bei den Teilnehmern zu klingeln.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Klingeln aktivieren", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Klingelton ausschalten", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Klingelton einschalten", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Weitere Optionen", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Du", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Deine Kamera ist ausgeschaltet", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Sicherheitsnummer anzeigen", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Nachricht", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Sicherheitsnummer anzeigen", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Rufnummer konnte nicht abgerufen werden. ÜberprĂŒfe deine Internetverbindung und versuche es erneut.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Bearbeitungen können nur innerhalb von 3 Stunden ab dem Senden dieser Nachricht vorgenommen werden.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Bearbeitungen können nur innerhalb von 24 Stunden ab dem Senden dieser Nachricht vorgenommen werden.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Diese Nachricht wurde gelöscht.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Anhang ist zu groß zum Anzeigen.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Einige AnhĂ€nge sind zu groß zum Anzeigen.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Spendendetails können nicht abgerufen werden", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Nur Signal Beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Das Bearbeiten von Nachrichten ist nur fĂŒr Signal Beta Nutzer verfĂŒgbar. Wenn du eine Nachricht bearbeitest, ist sie nur fĂŒr Personen sichtbar, die die aktuelle Version von Signal Beta verwenden.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Nachricht bearbeiten", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Wenn du eine Nachricht bearbeitest, ist sie nur fĂŒr Personen sichtbar, die die neuesten Versionen von Signal verwenden. Sie können dann sehen, dass du eine Nachricht bearbeitet hast.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Eingehender Videoanruf 
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Ausgehender Sprachanruf", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Ausgehender Videoanruf", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ruft dich gerade an", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Neu verbinden 
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} Person} other {{count,number} Personen}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Sprachanruf", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Ende", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Verlassen", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon aus", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon an", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Klingelton an", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Klingelton aus", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Einstellungen", @@ -3468,13 +3668,25 @@ "messageformat": "Anruf maximieren", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Zur Rasteransicht wechseln", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Ansicht Ă€ndern", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Zur Sprecheransicht wechseln", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Rasteransicht", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Seitenleistenansicht", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Sprecher*in-Ansicht", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Ansicht aktualisiert", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Anruf verlassen", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Nachricht kann nicht bearbeitet werden", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Diese Nachricht kann nur {max,number}-mal bearbeitet werden.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Sorry, dieser sgnl://-Link ergab keinen Sinn.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Username", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Mit deinem Nutzernamen ist etwas schief gelaufen, er ist deinem Konto nicht mehr zugeordnet.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Nutzername löschen", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Nutzername erstellen", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-Code oder Link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Der Nutzername muss zurĂŒckgesetzt werden", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Der Link zum Nutzernamen muss zurĂŒckgesetzt werden", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Teile deinen Nutzernamen mit anderen", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Nutzername löschen", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Dies entfernt deinen Nutzernamen. Danach werden andere Nutzer ihn ĂŒbernehmen können. Bist du sicher?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Hierdurch wird dein Nutzername entfernt und dein QR-Code und dein Link werden deaktiviert. »{username}« kann dann auch von anderen verwendet werden. Bist du dir sicher?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Du wirst keine Storys mehr teilen oder betrachten können. Story-Updates, die du kĂŒrzlich geteilt hast, werden ebenfalls gelöscht.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Sprache", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Sprache", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Systemsprache", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Sprachen suchen", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Keine Ergebnisse fĂŒr »{searchTerm}«", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Festlegen", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "FĂŒr die Anwendung Signal neu starten", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Um die Sprache zu Ă€ndern, muss die App neu gestartet werden.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Neu starten", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Aktualisierung auf Version {version} verfĂŒgbar", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Beim Speichern deiner Einstellungen ist ein Fehler aufgetreten. Versuche es bitte erneut.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Nachricht", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Weitere Designs", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ZurĂŒcksetzen", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Fertig", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Farbe des Nutzernamen-Links, {index,number} von {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Wenn du deinen QR-Code zurĂŒcksetzt, funktionieren dein bisheriger QR-Code und dein Link nicht mehr.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Link wird zurĂŒckgesetzt
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-Code und Link nicht festgelegt. ÜberprĂŒfe deine Netzverbindung und versuche es erneut.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Richte deinen Signal-Nutzernamen ein", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "Erneut senden", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Weitere Aktionen", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Anrufe", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Neuer Anruf", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Neuer Anruf", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Weitere Aktionen", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Anrufverlauf leeren", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Anrufverlauf leeren?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Dies wird den gesamten Anrufverlauf unwiderruflich löschen", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Entfernen", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Anrufliste geleert", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Zum Anzeigen oder Starten eines Anrufs klicken", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Suchen", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Nach Entgangen filtern", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Umschalten", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Keine aktuellen Anrufe. Leg los und rufe eine Freundin oder einen Freund an.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Keine Ergebnisse fĂŒr »{query}«", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Eingehend", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Ausgehend", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Verpasst", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Gruppenanruf", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Keine aktuellen Unterhaltungen.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Keine Ergebnisse fĂŒr »{query}«", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Ausgehender Sprachanruf} other {Eingehender Sprachanruf}}} Video {{direction, select, Outgoing {Ausgehender Videoanruf} other {Eingehender Videoanruf}}} Group {{direction, select, Outgoing {Ausgehender Gruppenanruf} other {Eingehender Gruppenanruf}}} other {{direction, select, Outgoing {Ausgehender Anruf} other {Eingehender Anruf}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Entgangener Sprachanruf} Video {Entgangener Videoanruf} Group {Entgangener Gruppenanruf} other {Entgangener Anruf}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Unbeantworteter Sprachanruf} Video {Unbeantworteter Videoanruf} Group {Unbeantworteter Gruppenanruf} other {Unbeantworteter Anruf}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Abgelehnter Sprachanruf} Video {Abgelehnter Videoanruf} Group {Abgelehnter Gruppenanruf} other {Abgelehnter Anruf}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} andere*r schreibt etwas.} other {{count,number} andere schreiben etwas.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Was ist neu", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Kleine Optimierungen, Fehlerbehebungen und Leistungsverbesserungen. Danke, dass du Signal nutzt!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Dieses Update beinhaltet einige Verbesserungen fĂŒr Sprach- und Videoanrufe sowie kleinere Updates der Dokumentation (danke, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Jetzt kannst du deine gewĂ€hlte Sprache in Signal wechseln, ohne deine Systemeinstellungen Ă€ndern zu mĂŒssen (Signal-Einstellungen > Darstellung > Sprache)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Wir haben die Benachrichtigungssymbole geĂ€ndert, die bei Gruppenaktualisierungen angezeigt werden, wenn beispielsweise jemand einer Gruppe neu hinzugefĂŒgt wird. Diese Symbole verbessern die Lesbarkeit, vor allem dann, wenn die Dunkelheit deine VerbĂŒndete ist. Bisher hatten sich die Symbole die Dunkelheit nur angeeignet. Die neuen Symbole hingegen wurden in ihr geboren, von ihr geformt." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Wir haben eine kurze Verzögerung behoben, die manchmal beim Beitreten zu einer Anrufwartelounge auf macOS-GerĂ€ten auftrat. So fĂ€llt zumindest eine Ausrede fĂŒr die halbsekĂŒndige VerspĂ€tung zum Meeting weg." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Wir haben die Übergangsanimation fĂŒr Videokacheln – wenn jemand einem Gruppenanruf beitritt oder ihn verlĂ€sst – verbessert. Wenn jetzt das Gesicht eines Freundes oder einer Freundin auftaucht, ist das eine »soziale Bewegung«." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Jetzt kannst du auf ein Profilfoto oder einen Gruppenavatar in der Chat-Kopfzeile klicken, um schnell auf die Chat-Einstellungen zuzugreifen oder um dir alle ungesehenen Storys aus diesem Chat anzusehen. Danke, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/el/messages.json b/_locales/el/messages.json index c02fe81706..629a791af2 100644 --- a/_locales/el/messages.json +++ b/_locales/el/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ÎŁÏ†ÎŹÎ»ÎŒÎ± στη ÎČÎŹÏƒÎ· ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÏ‰Îœ", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Î ÏÎżÎ­ÎșυψΔ ÏƒÏ†ÎŹÎ»ÎŒÎ± ÎČÎŹÏƒÎ·Ï‚ ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÏ‰Îœ. ÎœÏ€ÎżÏÎ”ÎŻÏ‚ Μα αΜτÎčÎłÏÎŹÏˆÎ”Îčς Ï„Îż ÏƒÏ†ÎŹÎ»ÎŒÎ± ÎșαÎč Μα ΔπÎčÎșÎżÎčÎœÏ‰ÎœÎźÏƒÎ”Îčς ΌΔ τηΜ Ï…Ï€ÎżÏƒÏ„ÎźÏÎčΟη Signal ÎłÎčα Μα ΔπÎčÎ»Ï…ÎžÎ”ÎŻ Ï„Îż πρόÎČληΌα. Î•ÎŹÎœ πρέπΔÎč Μα χρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÎ”Îčς Ï„Îż Signal αΌέσως, ÎŒÏ€ÎżÏÎ”ÎŻÏ‚ Μα ÎŽÎčÎ±ÎłÏÎŹÏˆÎ”Îčς τα ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÎ± ÏƒÎżÏ… ÎșαÎč Μα ÎșÎŹÎœÎ”Îčς ΔπαΜΔÎșÎșÎŻÎœÎ·ÏƒÎ·.\n\nΕπÎčÎșÎżÎčΜώΜησΔ ΌΔ τηΜ Ï…Ï€ÎżÏƒÏ„ÎźÏÎčΟη: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź όλωΜ τωΜ ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÏ‰Îœ ÎșαÎč ΔπαΜΔÎșÎșÎŻÎœÎ·ÏƒÎ·", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÏ‰Îœ ÎșαÎč ΔπαΜΔÎșÎșÎŻÎœÎ·ÏƒÎ·", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ΟρÎčστÎčÎșÎź ÎŽÎčÎ±ÎłÏÎ±Ï†Îź όλωΜ τωΜ ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÏ‰Îœ;", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ÎŒÎ»Îż Ï„Îż ÎčÏƒÏ„ÎżÏÎčÎșό ÎŒÎ·ÎœÏ…ÎŒÎŹÏ„Ï‰Îœ ÎșαÎč τα Ï€ÎżÎ»Ï…ÎŒÎ­ÏƒÎ± ÏƒÎżÏ… Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†ÎżÏÎœ ÎżÏÎčστÎčÎșÎŹ από Î±Ï…Ï„Îź τη συσÎșÎ”Ï…Îź. Θα ÎŒÏ€ÎżÏÎ”ÎŻÏ‚ Μα χρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÎ”Îčς Ï„Îż Signal σΔ Î±Ï…Ï„Îź τη συσÎșÎ”Ï…Îź Î±Ï†ÎżÏ τη συΜΎέσΔÎčς ÎŸÎ±ÎœÎŹ. ΔΔΜ Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†ÎżÏÎœ ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÎ± από Ï„Îż τηλέφωΜό ÏƒÎżÏ….", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Η έÎșÎŽÎżÏƒÎ· της ÎČÎŹÏƒÎ·Ï‚ ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÏ‰Îœ ÏƒÎżÏ… ΎΔΜ ταÎčρÎčΏζΔÎč ΌΔ Î±Ï…Ï„Îź τηΜ έÎșÎŽÎżÏƒÎ· Ï„ÎżÏ… Signal. ΒΔÎČαÎčÏŽÏƒÎżÏ… ότÎč Î±ÎœÎżÎŻÎłÎ”Îčς τηΜ πÎčÎż πρόσφατη έÎșÎŽÎżÏƒÎ· Ï„ÎżÏ… Signal ÏƒÏ„ÎżÎœ Ï…Ï€ÎżÎ»ÎżÎłÎčÏƒÏ„Îź ÏƒÎżÏ….", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Î‘ÏÏ‡Î”ÎŻÎż", @@ -300,6 +316,70 @@ "messageformat": "ÎŁÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ”Ï‚", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ÎšÎŹÏ„Îč Ï€ÎźÎłÎ” στραÎČÎŹ ΌΔ Ï„Îż ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ…, ΎΔΜ αΜτÎčÏƒÏ„ÎżÎčÏ‡Î”ÎŻ Ï€Î»Î­ÎżÎœ ÏƒÏ„ÎżÎœ Î»ÎżÎłÎ±ÏÎčασΌό ÏƒÎżÏ…. ÎœÏ€ÎżÏÎ”ÎŻÏ‚ Μα ÎŽÎżÎșÎčÎŒÎŹÏƒÎ”Îčς Μα Ï„Îż ÏÏ…ÎžÎŒÎŻÏƒÎ”Îčς ÎŸÎ±ÎœÎŹ Îź Μα ΔπÎčλέΟΔÎčς έΜα ÎœÎ­Îż.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ΔÎčόρΞωση τώρα", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ÎšÎŹÏ„Îč Ï€ÎźÎłÎ” στραÎČÎŹ ΌΔ Ï„ÎżÎœ ÎșωΎÎčÎșό QR ÎșαÎč Ï„ÎżÎœ ÏƒÏÎœÎŽÎ”ÏƒÎŒÎż Ï„ÎżÏ… ÎżÎœÏŒÎŒÎ±Ï„ÎżÏ‚ Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ…, ΎΔΜ ÎčσχύΔÎč Ï€Î»Î­ÎżÎœ. ΔηΌÎčÎżÏÏÎłÎ·ÏƒÎ” έΜαΜ ÎœÎ­Îż ÏƒÏÎœÎŽÎ”ÏƒÎŒÎż ÎłÎčα ÎșÎżÎčÎœÎź Ï‡ÏÎźÏƒÎ· ΌΔ Ώλλα ÎŹÏ„ÎżÎŒÎ±.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ΔÎčόρΞωση τώρα", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Î•ÎŒÏ†ÎŹÎœÎčση ÎșαρτΔλώΜ", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ΑπόÎșρυψη ÎșαρτΔλώΜ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Î Î±ÏÎżÏ…ÏƒÎčÎŹÏƒÏ„Î·ÎșΔ ÏƒÏ†ÎŹÎ»ÎŒÎ±", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} Όη Î±ÎœÎ±ÎłÎœÏ‰ÏƒÎŒÎ­ÎœÎ±", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ΕπÎčÏƒÎ·ÎŒÎŹÎœÎžÎ·ÎșΔ ως Όη Î±ÎœÎ±ÎłÎœÏ‰ÏƒÎŒÎ­ÎœÎż", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ÎŁÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ”Ï‚", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ÎšÎ»ÎźÏƒÎ”Îčς", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Î™ÏƒÏ„ÎżÏÎŻÎ”Ï‚", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ÎĄÏ…ÎžÎŒÎŻÏƒÎ”Îčς", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ΑΜαÎČÎŹÎžÎŒÎčση Ï„ÎżÏ… Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Î ÏÎżÏ†ÎŻÎ»", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Î ÎŻÏƒÏ‰", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Αυτές ÎżÎč ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ”Ï‚ Î”ÎŻÎœÎ±Îč αρχΔÎčÎżÎžÎ”Ï„Î·ÎŒÎ­ÎœÎ”Ï‚ ÎșαÎč Ξα ΔΌφαΜÎčÏƒÏ„ÎżÏÎœ στα ΔÎčσΔρχόΌΔΜα ÎŒÏŒÎœÎż αΜ Î»Î·Ï†ÎžÎżÏÎœ Μέα ΌηΜύΌατα.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ÎšÎ»ÎźÏƒÎ· παρ' όλα Î±Ï…Ï„ÎŹ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ÎŁÏ…ÎŒÎŒÎ”Ï„ÎżÏ‡Îź παρ' όλα Î±Ï…Ï„ÎŹ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ÎŁÏ…ÎœÎ­Ï‡Î”Îčα ÎșÎ»ÎźÏƒÎ·Ï‚", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ΟÎč αρÎčÎžÎŒÎżÎŻ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚ Î”ÎœÎ·ÎŒÎ”ÏÏŽÎœÎżÎœÏ„Î±Îč.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ÎœÎŹÎžÎ” πΔρÎčσσότΔρα", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Î ÏÎżÎ·ÎłÎżÏÎŒÎ”ÎœÎżÏ‚ αρÎčΞΌός Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Î•Ï€ÏŒÎŒÎ”ÎœÎżÏ‚ αρÎčΞΌός Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ΈÎșÎŽÎżÏƒÎ· αρÎčÎžÎŒÎżÏ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚, {index,number} από {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ÎŁÎ·ÎŒÎ”ÎŻÏ‰ÏƒÎ· ως ΔπÎčÎČΔÎČαÎčÏ‰ÎŒÎ­ÎœÎż", @@ -663,33 +747,41 @@ "messageformat": "Î‘Ï†Î±ÎŻÏÎ”ÏƒÎ· ΔπÎčÎČΔÎČÎ±ÎŻÏ‰ÏƒÎ·Ï‚", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "ΓÎčα Μα ΔπαληΞΔύσΔÎčς τηΜ ÎșÏÏ…Ï€Ï„ÎżÎłÏÎŹÏ†Î·ÏƒÎ· από ÎŹÎșÏÎż σΔ ÎŹÎșÏÎż ΌΔ Ï„ÎżÎœ Ï‡ÏÎźÏƒÏ„Î· {name}, ÏƒÏÎłÎșρÎčΜΔ Ï„ÎżÏ…Ï‚ Ï€Î±ÏÎ±Ï€ÎŹÎœÏ‰ αρÎčÎžÎŒÎżÏÏ‚ ΌΔ Î±Ï…Ï„ÎżÏÏ‚ στη συσÎșÎ”Ï…Îź Ï„ÎżÏ…. ÎœÏ€ÎżÏÎ”ÎŻ Î”Ï€ÎŻÏƒÎ·Ï‚ Μα σÎșÎ±ÎœÎŹÏÎ”Îč Ï„ÎżÎœ ÎșωΎÎčÎșό ÏƒÎżÏ… ΌΔ τη συσÎșÎ”Ï…Îź Ï„ÎżÏ….", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ÎœÎŹÎžÎ” πΔρÎčσσότΔρα", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "ΓÎčα Μα ΔπαληΞΔύσΔÎčς τηΜ ÎșÏÏ…Ï€Ï„ÎżÎłÏÎŹÏ†Î·ÏƒÎ· από ÎŹÎșÏÎż σΔ ÎŹÎșÏÎż ΌΔ Ï„ÎżÎœ Ï‡ÏÎźÏƒÏ„Î· {name}, αΜτÎčÏƒÏ„ÎżÎŻÏ‡ÎčσΔ τηΜ Î­ÎłÏ‡ÏÏ‰ÎŒÎ· ÎșÎŹÏÏ„Î± Ï€Î±ÏÎ±Ï€ÎŹÎœÏ‰ ΌΔ τη συσÎșÎ”Ï…Îź Ï„ÎżÏ… ÎșαÎč ÏƒÏ…ÎłÎșÏÎŻÎœÎ”Ï„Î” Ï„ÎżÏ…Ï‚ αρÎčÎžÎŒÎżÏÏ‚. Î•ÎŹÎœ ΎΔΜ ταÎčρÎčÎŹÎ¶ÎżÏ…Îœ, ÎŽÎżÎșÎŻÎŒÎ±ÏƒÎ” Ï„Îż Ώλλο Î¶Î”ÏÎłÎżÏ‚ αρÎčΞΌώΜ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚. ÎœÏŒÎœÎż έΜα Î¶Î”Ï…ÎłÎŹÏÎč χρΔÎčÎŹÎ¶Î”Ï„Î±Îč Μα ταÎčρÎčΏζΔÎč.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "ΓÎčα Μα ΔπαληΞΔύσΔÎčς τηΜ ÎșÏÏ…Ï€Ï„ÎżÎłÏÎŹÏ†Î·ÏƒÎ· από ÎŹÎșÏÎż σΔ ÎŹÎșÏÎż ΌΔ Ï„ÎżÎœ Ï‡ÏÎźÏƒÏ„Î· {name}, ÏƒÏÎłÎșρÎčΜΔ Ï„ÎżÏ…Ï‚ Ï€Î±ÏÎ±Ï€ÎŹÎœÏ‰ αρÎčÎžÎŒÎżÏÏ‚ ΌΔ Î±Ï…Ï„ÎżÏÏ‚ στη συσÎșÎ”Ï…Îź Ï„ÎżÏ…. ÎœÏ€ÎżÏÎ”ÎŻ Î”Ï€ÎŻÏƒÎ·Ï‚ Μα σÎșÎ±ÎœÎŹÏÎ”Îč Ï„ÎżÎœ ÎșωΎÎčÎșό ÏƒÎżÏ… ΌΔ τη συσÎșÎ”Ï…Îź Ï„ÎżÏ….", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Î‘Î»Î»Î±ÎłÎ­Ï‚ ÏƒÏ„ÎżÏ…Ï‚ ΑρÎčÎžÎŒÎżÏÏ‚ Î‘ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ΟÎč αρÎčÎžÎŒÎżÎŻ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚ Î”ÎœÎ·ÎŒÎ”ÏÏŽÎœÎżÎœÏ„Î±Îč ÎșÎ±Ï„ÎŹ τη ÎŽÎčÎŹÏÎșΔÎčα ÎŒÎčας ΌΔταÎČατÎčÎșÎźÏ‚ πΔρÎčÏŒÎŽÎżÏ… ÎłÎčα Μα Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčÎ·ÎžÎżÏÎœ ÎżÎč ΔπΔρχόΌΔΜΔς λΔÎčÏ„ÎżÏ…ÏÎłÎŻÎ”Ï‚ Î±Ï€ÎżÏÏÎźÏ„ÎżÏ… ÏƒÏ„Îż Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ΓÎčα Μα ΔπαληΞΔύσΔÎčς Ï„ÎżÏ…Ï‚ αρÎčÎžÎŒÎżÏÏ‚ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚, αΜτÎčÏƒÏ„ÎżÎŻÏ‡ÎčσΔ τηΜ Î­ÎłÏ‡ÏÏ‰ÎŒÎ· ÎșÎŹÏÏ„Î± ΌΔ τη συσÎșÎ”Ï…Îź της Î”Ï€Î±Ï†ÎźÏ‚ ÏƒÎżÏ…. Î•ÎŹÎœ ΎΔΜ ταÎčρÎčÎŹÎ¶ÎżÏ…Îœ, ÎŽÎżÎșÎŻÎŒÎ±ÏƒÎ” Ï„Îż Ώλλο Î¶Î”ÏÎłÎżÏ‚ αρÎčΞΌώΜ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚. ÎœÏŒÎœÎż έΜα Î¶Î”Ï…ÎłÎŹÏÎč χρΔÎčÎŹÎ¶Î”Ï„Î±Îč Μα ταÎčρÎčΏζΔÎč.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ΧρΔÎčÎŹÎ¶Î”ÏƒÎ±Îč ÎČοΟΞΔÎčα;", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Î•ÎœÏ„ÎŹÎŸÎ”Îč", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Θα ΎηΌÎčÎżÏ…ÏÎłÎ·ÎžÎ”ÎŻ έΜας αρÎčΞΌός Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚ ΌΔ αυτό Ï„Îż ÎŹÏ„ÎżÎŒÎż Î±Ï†ÎżÏ Î±ÎœÏ„Î±Î»Î»ÎŹÎŸÎ”Ï„Î” ΌηΜύΌατα ΌΔταΟύ σας.", @@ -1267,10 +1359,6 @@ "messageformat": "Î ÏÎżÎČολΟ πρόσφατωΜ Ï€ÎżÎ»Ï…ÎŒÎ­ÏƒÏ‰Îœ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "ΓÎčα Μα ΔπαληΞΔύσΔÎčς τηΜ ÎșÏÏ…Ï€Ï„ÎżÎłÏÎŹÏ†Î·ÏƒÎ· από ÎŹÎșÏÎż σΔ ÎŹÎșÏÎż ΌΔ Ï„ÎżÎœ Ï‡ÏÎźÏƒÏ„Î· {name}, ÏƒÏÎłÎșρÎčΜΔ Ï„ÎżÏ…Ï‚ Ï€Î±ÏÎ±Ï€ÎŹÎœÏ‰ αρÎčÎžÎŒÎżÏÏ‚ ΌΔ Î±Ï…Ï„ÎżÏÏ‚ στη συσÎșÎ”Ï…Îź Ï„ÎżÏ…. ÎœÏ€ÎżÏÎ”ÎŻ Î”Ï€ÎŻÏƒÎ·Ï‚ Μα σÎșÎ±ÎœÎŹÏÎ”Îč Ï„ÎżÎœ ÎșωΎÎčÎșό qr Ï€Î±ÏÎ±Ï€ÎŹÎœÏ‰.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ΔΔΜ έχΔÎčς Î±ÎœÏ„Î±Î»Î»ÎŹÎŸÎ”Îč αÎșόΌα ΌηΜύΌατα ΌΔ Î±Ï…Ï„ÎźÎœ τηΜ Î”Ï€Î±Ï†Îź. Ο αρÎčΞΌός Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚ ÏƒÎżÏ… ΌΔ Î±Ï…Ï„Îź Ξα Î”ÎŻÎœÎ±Îč ÎŽÎčαΞέσÎčÎŒÎżÏ‚ ÎŒÎ”Ï„ÎŹ Ï„Îż Ï€ÏÏŽÏ„Îż ÎŒÎźÎœÏ…ÎŒÎ±." }, @@ -1334,17 +1422,17 @@ "messageformat": "Î Î»Î·ÏÎżÏ†ÎżÏÎŻÎ”Ï‚", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎŒÎ·ÎœÏ…ÎŒÎŹÏ„Ï‰Îœ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ±Ï‚;", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎŒÎ·ÎœÏ…ÎŒÎŹÏ„Ï‰Îœ;", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Î‘Ï…Ï„Îź η ÏƒÏ…ÎœÎżÎŒÎčλία Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†Î”ÎŻ από Î±Ï…Ï„Îź τη συσÎșÎ”Ï…Îź.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "΀α ΌηΜύΌατα σΔ Î±Ï…Ï„Îź τη ÏƒÏ…ÎœÎżÎŒÎčλία Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†ÎżÏÎœ από Î±Ï…Ï„Îź τη συσÎșÎ”Ï…Îź. ÎœÏ€ÎżÏÎ”ÎŻÏ‚ αÎșόΌα Μα ÎșÎŹÎœÎ”Îčς Î±ÎœÎ±Î¶ÎźÏ„Î·ÏƒÎ· Î±Ï…Ï„ÎźÏ‚ της ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ±Ï‚ Î±Ï†ÎżÏ ÎŽÎčÎ±ÎłÏÎŹÏˆÎ”Îčς ΌηΜύΌατα.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Î‘Ï€ÎżÏ‡ÏŽÏÎ·ÏƒÎ· απ' τηΜ ÎżÎŒÎŹÎŽÎ±", @@ -1438,6 +1526,14 @@ "messageformat": "΀ο ÎčÏƒÏ„ÎżÏÎčÎșό ÎŒÎ·ÎœÏ…ÎŒÎŹÏ„Ï‰Îœ ÏƒÎżÏ… ÎșαÎč ÎłÎčα τÎčς ÎŽÏÎż ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ”Ï‚ έχΔÎč ÏƒÏ…ÎłÏ‡Ï‰ÎœÎ”Ï…Ï„Î”ÎŻ ΔΎώ.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "Ο αρÎčΞΌός {phoneNumber} Î±ÎœÎźÎșΔÎč ÏƒÏ„ÎżÎœ Ï‡ÏÎźÏƒÏ„Î· {conversationTitle}. Î•ÎŻÏƒÏ„Î” ÎșαÎč ÎżÎč ÎŽÏÎż Όέλη της ÎżÎŒÎŹÎŽÎ±Ï‚ {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "Ο αρÎčΞΌός {phoneNumber} Î±ÎœÎźÎșΔÎč ÏƒÏ„ÎżÎœ Ï‡ÏÎźÏƒÏ„Î· {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ΜÎčÎșÏÎżÎłÏÎ±Ï†ÎŻÎ± της ΔÎčÎșόΜας από Ï„Îż Î±ÎœÎ±Ï†Î”ÏÏŒÎŒÎ”ÎœÎż ÎŒÎźÎœÏ…ÎŒÎ±", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Î•Ï€Î±ÎœÎŹÎșληση", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ΈΜαρΟη ÎșÎ»ÎźÏƒÎ·Ï‚", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Î•ÎŻÏƒÎżÎŽÎżÏ‚ στηΜ ÎșÎ»ÎźÏƒÎ·", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "΀ο ÎŒÎčÎșÏÏŒÏ†Ï‰ÎœÎż Î”ÎŻÎœÎ±Îč σΔ ÏƒÎŻÎłÎ±ÏƒÎ· Î»ÏŒÎłÏ‰ Ï„ÎżÏ… ÎŒÎ”ÎłÎ­ÎžÎżÏ…Ï‚ Î±Ï…Ï„ÎźÏ‚ της ÎșÎ»ÎźÏƒÎ·Ï‚", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ΕÎčÎŽÎżÏ€ÎżÎčÎźÏƒÎ”Îčς ÎșÎ»ÎźÏƒÎ”Ï‰Îœ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Η ÎșÎ»ÎźÏƒÎ· Î”ÎŻÎœÎ±Îč ÎłÎ”ÎŒÎŹÏ„Î·", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ÎšÎŹÎŒÎ”ÏÎ±", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ÎŁÏ…ÎŒÎŒÎ”Ï„ÎżÏ‡Îź", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ΕÎșÎșÎŻÎœÎ·ÏƒÎ·", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Η ÎșÎ»ÎźÏƒÎ· Î”ÎŻÎœÎ±Îč ÎłÎ”ÎŒÎŹÏ„Î·", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ÎšÎŹÎŒÎ”ÏÎ± Î±Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčηΌέΜη", @@ -1621,10 +1725,6 @@ "messageformat": "Î•ÎœÎ”ÏÎłÎżÏ€ÎżÎŻÎ·ÏƒÎ· ÎșÎŹÎŒÎ”ÏÎ±Ï‚", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ÎŁÎŻÎłÎ±ÏƒÎ·", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "ΜÎčÎșÏÏŒÏ†Ï‰ÎœÎż Î±Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčÎ·ÎŒÎ­ÎœÎż", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Î•ÎœÎ”ÏÎłÎżÏ€ÎżÎŻÎ·ÏƒÎ· ÎŒÎčÎșÏÎżÏ†ÏŽÎœÎżÏ…", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ΜοÎčÏÎŹÏƒÎżÏ…", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Η Ï€Î±ÏÎżÏ…ÏƒÎŻÎ±ÏƒÎ· Î”ÎŻÎœÎ±Îč Î±Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčηΌέΜη", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Î›ÎźÎŸÎ· Ï€Î±ÏÎżÏ…ÏƒÎŻÎ±ÏƒÎ·Ï‚", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ÎšÎżÏ…ÎŽÎżÏÎœÎčσΌα", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Η ÎżÎŒÎŹÎŽÎ± Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Î· ώστΔ Μα ÎșÎ±Î»Î­ÏƒÎżÏ…ÎŒÎ” ΌΔ ÎșÎżÏ…ÎŽÎżÏÎœÎčσΌα Ï„ÎżÏ…Ï‚ ÏƒÏ…ÎŒÎŒÎ”Ï„Î­Ï‡ÎżÎœÏ„Î”Ï‚.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Î•ÎœÎ”ÏÎłÎżÏ€ÎżÎŻÎ·ÏƒÎ· ÎșÎżÏ…ÎŽÎżÏ…ÎœÎŻÏƒÎŒÎ±Ï„ÎżÏ‚", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Î‘Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎŻÎ·ÏƒÎ· ÎșÎżÏ…ÎŽÎżÏ…ÎœÎŻÏƒÎŒÎ±Ï„ÎżÏ‚", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Î•ÎœÎ”ÏÎłÎżÏ€ÎżÎŻÎ·ÏƒÎ· ÎșÎżÏ…ÎŽÎżÏ…ÎœÎŻÏƒÎŒÎ±Ï„ÎżÏ‚", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ΠΔρÎčσσότΔρΔς ΔπÎčÎ»ÎżÎłÎ­Ï‚", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Εσύ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Η ÎșÎŹÎŒÎ”ÏÎŹ ÏƒÎżÏ… Î”ÎŻÎœÎ±Îč Î±Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčηΌέΜη", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Î•ÎŒÏ†ÎŹÎœÎčση αρÎčÎžÎŒÎżÏ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ÎœÎźÎœÏ…ÎŒÎ±", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Î•ÎŒÏ†ÎŹÎœÎčση αρÎčÎžÎŒÎżÏ Î±ÏƒÏ†Î±Î»Î”ÎŻÎ±Ï‚", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Î‘Ï€ÎżÏ„Ï…Ï‡ÎŻÎ± Î»ÎźÏˆÎ·Ï‚ Ï„ÎżÏ… τηλΔφωΜÎčÎșÎżÏ αρÎčÎžÎŒÎżÏ. ÎˆÎ»Î”ÎłÎŸÎ” τη ÏƒÏÎœÎŽÎ”ÏƒÎź ÏƒÎżÏ… ÎșαÎč Ï€ÏÎżÏƒÏ€ÎŹÎžÎ·ÏƒÎ” ÎŸÎ±ÎœÎŹ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ΟÎč Ï„ÏÎżÏ€ÎżÏ€ÎżÎčÎźÏƒÎ”Îčς ÎŒÏ€ÎżÏÎżÏÎœ Μα Î”Ï†Î±ÏÎŒÎżÏƒÏ„ÎżÏÎœ ÎŒÏŒÎœÎż ΔΜτός 3 ωρώΜ από τη στÎčÎłÎŒÎź Ï€ÎżÏ… έστΔÎčλΔς αυτό Ï„Îż ÎŒÎźÎœÏ…ÎŒÎ±.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ΟÎč Ï„ÏÎżÏ€ÎżÏ€ÎżÎčÎźÏƒÎ”Îčς ÎŒÏ€ÎżÏÎżÏÎœ Μα Î”Ï†Î±ÏÎŒÎżÏƒÏ„ÎżÏÎœ ÎŒÏŒÎœÎż ΔΜτός 24 ωρώΜ από τη στÎčÎłÎŒÎź Ï€ÎżÏ… έστΔÎčλΔς αυτό Ï„Îż ÎŒÎźÎœÏ…ÎŒÎ±.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Αυτό Ï„Îż ÎŒÎźÎœÏ…ÎŒÎ± ÎŽÎčÎ±ÎłÏÎŹÏ†Ï„Î·ÎșΔ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "΀ο ÏƒÏ…ÎœÎ·ÎŒÎŒÎ­ÎœÎż Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Îż ÎłÎčα Î”ÎŒÏ†ÎŹÎœÎčση.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ΟρÎčσΌέΜα συΜηΌΌέΜα Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Î± ÎłÎčα Î”ÎŒÏ†ÎŹÎœÎčση.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Î‘ÎŽÏ…ÎœÎ±ÎŒÎŻÎ± Î±ÎœÎŹÎșτησης ÏƒÏ„ÎżÎčÏ‡Î”ÎŻÏ‰Îœ ÎŽÏ‰ÏÎ”ÎŹÏ‚", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ÎœÏŒÎœÎż στηΜ beta έÎșÎŽÎżÏƒÎ· Ï„ÎżÏ… Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Η Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ± ÎŒÎ·ÎœÏ…ÎŒÎŹÏ„Ï‰Îœ Î”ÎŻÎœÎ±Îč ÎŽÎčαΞέσÎčΌη ÎŒÏŒÎœÎż ÏƒÏ„ÎżÏ…Ï‚ Ï‡ÏÎźÏƒÏ„Î”Ï‚ beta Ï„ÎżÏ… Signal. Î•ÎŹÎœ Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÏ„Î”ÎŻÏ‚ έΜα ÎŒÎźÎœÏ…ÎŒÎ±, Ξα Î”ÎŻÎœÎ±Îč ÎżÏÎ±Ï„ÏŒ ÎŒÏŒÎœÎż σΔ ÎŹÏ„ÎżÎŒÎ± Ï€ÎżÏ… ÎČÏÎŻÏƒÎșÎżÎœÏ„Î±Îč στηΜ Ï„Î”Î»Î”Ï…Ï„Î±ÎŻÎ± beta έÎșÎŽÎżÏƒÎ· Ï„ÎżÏ… Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Î•Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ± ÎŒÎ·ÎœÏÎŒÎ±Ï„ÎżÏ‚", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Î•ÎŹÎœ Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÏ„Î”ÎŻÏ‚ έΜα ÎŒÎźÎœÏ…ÎŒÎ±, Ξα Î”ÎŻÎœÎ±Îč ÎżÏÎ±Ï„ÏŒ ÎŒÏŒÎœÎż σΔ ÎŹÏ„ÎżÎŒÎ± Ï€ÎżÏ… χρησÎčÎŒÎżÏ€ÎżÎčÎżÏÎœ τÎčς Ï„Î”Î»Î”Ï…Ï„Î±ÎŻÎ”Ï‚ ΔÎșΎόσΔÎčς Ï„ÎżÏ… Signal. ΔΔΜ Ξα ÎŒÏ€ÎżÏÎżÏÎœ Μα ÎŽÎżÏ…Îœ ότÎč Î”Ï€Î”ÎŸÎ”ÏÎłÎŹÏƒÏ„Î·ÎșΔς Ï„Îż ÎŒÎźÎœÏ…ÎŒÎ±.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ΕÎčσΔρχόΌΔΜη ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "ΕΟΔρχόΌΔΜη ÎșÎ»ÎźÏƒÎ·", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ΕΟΔρχόΌΔΜη ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "Ο/Η {ringer} σΔ ÎșαλΔί", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ΕπαΜασύΜΎΔση ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} ÎŹÏ„ÎżÎŒÎż} other {{count,number} ÎŹÏ„ÎżÎŒÎ±}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ΗχητÎčÎșÎź ÎșÎ»ÎźÏƒÎ·", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Î€Î­Î»ÎżÏ‚", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Î‘Ï€ÎżÏ‡ÏŽÏÎ·ÏƒÎ·", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "ΜÎčÎșÏÏŒÏ†Ï‰ÎœÎż Î±ÎœÎ”ÎœÎ”ÏÎłÏŒ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "ΜÎčÎșÏÏŒÏ†Ï‰ÎœÎż Î”ÎœÎ”ÏÎłÏŒ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ÎšÎżÏ…ÎŽÎżÏÎœÎčσΌα Î”ÎœÎ”ÏÎłÏŒ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ÎšÎżÏ…ÎŽÎżÏÎœÎčσΌα Î±ÎœÎ”ÎœÎ”ÏÎłÏŒ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ÎĄÏ…ÎžÎŒÎŻÏƒÎ”Îčς", @@ -3468,13 +3668,25 @@ "messageformat": "ÎšÎ»ÎźÏƒÎ· σΔ Ï€Î»ÎźÏÎ· ÎżÎžÏŒÎœÎ·", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ΑλλαγΟ σΔ Ï€ÏÎżÎČολΟ σΔ Ï€Î»Î­ÎłÎŒÎ±", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ΑλλαγΟ Ï€ÏÎżÎČÎżÎ»ÎźÏ‚", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ΑλλαγΟ σΔ Ï€ÏÎżÎČολΟ ÎżÎŒÎčÎ»Î·Ï„Îź", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Î ÏÎżÎČολΟ σΔ Ï€Î»Î­ÎłÎŒÎ±", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Î ÏÎżÎČολΟ ÏƒÏ„Îż Ï€Î»ÎŹÎč", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Î ÏÎżÎČολΟ ÎżÎŒÎčÎ»Î·Ï„Îź", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Η Ï€ÏÎżÎČολΟ ΔΜηΌΔρώΞηÎșΔ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Î‘Ï€ÎżÏ‡ÏŽÏÎ·ÏƒÎ· από τηΜ ÎșÎ»ÎźÏƒÎ·", @@ -3576,6 +3788,14 @@ "messageformat": "Î•ÎœÏ„ÎŹÎŸÎ”Îč", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ΔΔΜ Î”ÎŻÎœÎ±Îč ÎŽÏ…ÎœÎ±Ï„Îź η Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ± Ï„ÎżÏ… ÎŒÎ·ÎœÏÎŒÎ±Ï„ÎżÏ‚", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ÎœÏ€ÎżÏÎ”ÎŻ Μα ÎłÎŻÎœÎ”Îč Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ± σΔ αυτό Ï„Îż ÎŒÎźÎœÏ…ÎŒÎ± ÎŒÏŒÎœÎż {max,number} Ï†ÎżÏÎ­Ï‚.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ÎŁÏ…ÎłÎłÎœÏŽÎŒÎ·, αυτός Îż ÏƒÏÎœÎŽÎ”ÏƒÎŒÎżÏ‚ sgnl:// ΎΔΜ ÎČγΏζΔÎč ΜόηΌα!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ÎŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î·", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ÎšÎŹÏ„Îč Ï€ÎźÎłÎ” στραÎČÎŹ ΌΔ Ï„Îż ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ…, ΎΔΜ αΜτÎčÏƒÏ„ÎżÎčÏ‡Î”ÎŻ Ï€Î»Î­ÎżÎœ ÏƒÏ„ÎżÎœ Î»ÎżÎłÎ±ÏÎčασΌό ÏƒÎżÏ….", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎżÎœÏŒÎŒÎ±Ï„ÎżÏ‚ Ï‡ÏÎźÏƒÏ„Î·", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ΔηΌÎčÎżÏ…ÏÎłÎŻÎ± ÎżÎœÏŒÎŒÎ±Ï„ÎżÏ‚ Ï‡ÏÎźÏƒÏ„Î·", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "ΚωΎÎčÎșός QR Îź ÎŁÏÎœÎŽÎ”ÏƒÎŒÎżÏ‚", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "΀ο ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· χρΔÎčÎŹÎ¶Î”Ï„Î±Îč Î”Ï€Î±ÎœÎ±Ï†ÎżÏÎŹ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Ο ÏƒÏÎœÎŽÎ”ÏƒÎŒÎżÏ‚ ÎżÎœÏŒÎŒÎ±Ï„ÎżÏ‚ Ï‡ÏÎźÏƒÏ„Î· χρΔÎčÎŹÎ¶Î”Ï„Î±Îč Î”Ï€Î±ÎœÎ±Ï†ÎżÏÎŹ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ΜοÎčÏÎŹÏƒÎżÏ… Ï„Îż ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ…", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎżÎœÏŒÎŒÎ±Ï„ÎżÏ‚ Ï‡ÏÎźÏƒÏ„Î·", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Î‘Ï…Ï„Îź η Î”ÎœÎ­ÏÎłÎ”Îčα Ξα αφαÎčρέσΔÎč Ï„Îż ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ… ÎșαÎč ΏλλοÎč Ï‡ÏÎźÏƒÏ„Î”Ï‚ Ξα ÎŒÏ€ÎżÏÎżÏÎœ Μα Ï„Îż χρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÎżÏ…Îœ. Î•ÎŻÏƒÎ±Îč ÏƒÎŻÎłÎżÏ…ÏÎżÏ‚/η;", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Αυτό Ξα ÎșÎ±Ï„Î±ÏÎłÎźÏƒÎ”Îč Ï„Îż ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ… ÎșαÎč Ξα Î±Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčÎźÏƒÎ”Îč Ï„ÎżÎœ ÎșωΎÎčÎșό QR ÎșαÎč Ï„ÎżÎœ σύΜΎΔσΌό ÏƒÎżÏ…. ΀ο ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· “{username}” Ξα Î”ÎŻÎœÎ±Îč ÎŽÎčαΞέσÎčÎŒÎż σΔ ÎŹÎ»Î»ÎżÏ…Ï‚ Ï‡ÏÎźÏƒÏ„Î”Ï‚. Î•ÎŻÏƒÎ±Îč ÏƒÎŻÎłÎżÏ…ÏÎżÏ‚/η;", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ΔΔΜ Ξα ÎŒÏ€ÎżÏÎ”ÎŻÏ‚ Ï€Î»Î­ÎżÎœ Μα ÎŒÎżÎčÏÎŹÎ¶Î”ÏƒÎ±Îč Îź Μα ÎČλέπΔÎčς ÎčÏƒÏ„ÎżÏÎŻÎ”Ï‚. ΟÎč ΔΜηΌΔρώσΔÎčς ÎčÏƒÏ„ÎżÏÎŻÎ±Ï‚ Ï€ÎżÏ… ÎșÎżÎčÎœÎżÏ€ÎżÎŻÎ·ÏƒÎ”Ï‚ πρόσφατα Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†ÎżÏÎœ Î”Ï€ÎŻÏƒÎ·Ï‚.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Γλώσσα", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Γλώσσα", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Γλώσσα ÏƒÏ…ÏƒÏ„ÎźÎŒÎ±Ï„ÎżÏ‚", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Î‘ÎœÎ±Î¶ÎźÏ„Î·ÏƒÎ· ÎłÎ»Ï‰ÏƒÏƒÏŽÎœ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ΔΔΜ ÎČρέΞηÎșαΜ Î±Ï€ÎżÏ„Î”Î»Î­ÏƒÎŒÎ±Ï„Î± ÎłÎčα “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ΟρÎčσΌός", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ÎšÎŹÎœÎ” ΔπαΜΔÎșÎșÎŻÎœÎ·ÏƒÎ· Ï„Îż Signal ÎłÎčα Μα ÎłÎŻÎœÎ”Îč Î”Ï†Î±ÏÎŒÎżÎłÎź", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ΓÎčα Μα Î±Î»Î»ÎŹÎŸÎ”Îč η ÎłÎ»ÏŽÏƒÏƒÎ±, πρέπΔÎč Μα ÎłÎŻÎœÎ”Îč ΔπαΜΔÎșÎșÎŻÎœÎ·ÏƒÎ· της Î”Ï†Î±ÏÎŒÎżÎłÎźÏ‚.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ΕπαΜΔÎșÎșÎŻÎœÎ·ÏƒÎ·", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ΑΜαÎČÎŹÎžÎŒÎčση στη ÎŽÎčαΞέσÎčΌη έÎșÎŽÎżÏƒÎ· {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Î„Ï€ÎźÏÎŸÎ” ÎșÎŹÏ€ÎżÎčÎż ÏƒÏ†ÎŹÎ»ÎŒÎ± ΌΔ τηΜ Î±Ï€ÎżÎžÎźÎșΔυση τωΜ ÏÏ…ÎžÎŒÎŻÏƒÎ”ÏŽÎœ ÏƒÎżÏ…. ΠαραÎșαλώ ÎŸÎ±ÎœÎ±Ï€ÏÎżÏƒÏ€ÎŹÎžÎ·ÏƒÎ” Î±ÏÎłÏŒÏ„Î”ÏÎ±.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ÎœÎźÎœÏ…ÎŒÎ±", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ΠΔρÎčσσότΔρα στÎčλ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Î•Ï€Î±ÎœÎ±Ï†ÎżÏÎŹ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Î€Î­Î»ÎżÏ‚", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ΧρώΌα ÏƒÏ…ÎœÎŽÎ­ÏƒÎŒÎżÏ… ÎżÎœÏŒÎŒÎ±Ï„ÎżÏ‚ Ï‡ÏÎźÏƒÏ„Î·, {index,number} από {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Î•ÎŹÎœ ΔπαΜαφέρΔÎčς Ï„ÎżÎœ ÎșωΎÎčÎșό QR ÏƒÎżÏ…, Îż Ï…Ï€ÎŹÏÏ‡Ï‰Îœ ÎșωΎÎčÎșός QR ÎșαÎč Îż σύΜΎΔσΌός ÏƒÎżÏ… ΎΔΜ Ξα λΔÎčÏ„ÎżÏ…ÏÎłÎżÏÎœ Ï€Î»Î­ÎżÎœ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Î•Ï€Î±ÎœÎ±Ï†ÎżÏÎŹ ÏƒÏ…ÎœÎŽÎ­ÏƒÎŒÎżÏ…...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Ο ÎșωΎÎčÎșός QR ÎșαÎč Îż ÏƒÏÎœÎŽÎ”ÏƒÎŒÎżÏ‚ ΎΔΜ Î­Ï‡ÎżÏ…Îœ ÎżÏÎčÏƒÏ„Î”ÎŻ. ÎˆÎ»Î”ÎłÎŸÎ” τη ÏƒÏÎœÎŽÎ”ÏƒÎź ÏƒÎżÏ… ÏƒÏ„Îż ÎŽÎŻÎșÏ„Ï…Îż ÎșαÎč ÎŽÎżÎșÎŻÎŒÎ±ÏƒÎ” Ï€ÎŹÎ»Îč.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ÎĄÏÎžÎŒÎčσΔ Ï„Îż ÏŒÎœÎżÎŒÎ± Ï‡ÏÎźÏƒÏ„Î· ÏƒÎżÏ… ÏƒÏ„Îż Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "έγÎčΜΔ Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ±", + "messageformat": "ΈγÎčΜΔ Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ±", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Î•Ï€Î±ÎœÎ±Ï€ÎżÏƒÏ„ÎżÎ»Îź", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ΠΔρÎčσσότΔρΔς Î”ÎœÎ­ÏÎłÎ”ÎčΔς", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ÎšÎ»ÎźÏƒÎ”Îčς", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Νέα ÎșÎ»ÎźÏƒÎ·", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Νέα ÎșÎ»ÎźÏƒÎ·", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ΠΔρÎčσσότΔρΔς Î”ÎœÎ­ÏÎłÎ”ÎčΔς", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎčÏƒÏ„ÎżÏÎčÎșÎżÏ ÎșÎ»ÎźÏƒÎ”Ï‰Îœ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ΔÎčÎ±ÎłÏÎ±Ï†Îź ÎčÏƒÏ„ÎżÏÎčÎșÎżÏ ÎșÎ»ÎźÏƒÎ”Ï‰Îœ;", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ΜΔ Î±Ï…Ï„Îź τηΜ ΔπÎčλογΟ Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†Î”ÎŻ ΌόΜÎčΌα Ï„Îż ÎčÏƒÏ„ÎżÏÎčÎșό ÎșÎ»ÎźÏƒÎ”Ï‰Îœ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ΕÎșÎșÎ±ÎžÎŹÏÎčση", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "΀ο ÎčÏƒÏ„ÎżÏÎčÎșό ÎșÎ»ÎźÏƒÎ”Ï‰Îœ ÎŽÎčÎ±ÎłÏÎŹÏ†Î·ÎșΔ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ÎšÎŹÎœÎ” ÎșλÎčÎș ÎłÎčα Μα ΎΔÎčς Îź Μα ΟΔÎșÎčÎœÎźÏƒÎ”Îčς ÎŒÎčα ÎșÎ»ÎźÏƒÎ·", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Î‘ÎœÎ±Î¶ÎźÏ„Î·ÏƒÎ·", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ÎŠÎŻÎ»Ï„ÏÎż Î±ÎœÎŹ Î±ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î”Ï‚", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Î•ÎœÎ”ÏÎłÎżÏ€ÎżÎŻÎ·ÏƒÎ·", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ΔΔΜ Ï…Ï€ÎŹÏÏ‡ÎżÏ…Îœ πρόσφατΔς ÎșÎ»ÎźÏƒÎ”Îčς. ΞΔÎșÎŻÎœÎ± ÎșαλώΜτας ÎșÎŹÏ€ÎżÎčÎż φÎčÎ»Î±ÏÎŹÎșÎč.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ΔΔΜ ÎČρέΞηÎșαΜ Î±Ï€ÎżÏ„Î”Î»Î­ÏƒÎŒÎ±Ï„Î± ÎłÎčα “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ΕÎčσΔρχόΌΔΜη", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ΕΟΔρχόΌΔΜη", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î·", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ΟΌαΎÎčÎșÎź ÎșÎ»ÎźÏƒÎ·", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ΔΔΜ Ï…Ï€ÎŹÏÏ‡ÎżÏ…Îœ πρόσφατΔς ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ”Ï‚.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ΔΔΜ ÎČρέΞηÎșαΜ Î±Ï€ÎżÏ„Î”Î»Î­ÏƒÎŒÎ±Ï„Î± ÎłÎčα “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {ΕΟΔρχόΌΔΜη ÎșÎ»ÎźÏƒÎ·} other {ΕÎčσΔρχόΌΔΜη ÎșÎ»ÎźÏƒÎ·}}} Video {{direction, select, Outgoing {ΕΟΔρχόΌΔΜη ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·} other {ΕÎčσΔρχόΌΔΜη ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·}}} Group {{direction, select, Outgoing {ΕΟΔρχόΌΔΜη ÎżÎŒÎ±ÎŽÎčÎșÎź ÎșÎ»ÎźÏƒÎ·} other {ΕÎčσΔρχόΌΔΜη ÎżÎŒÎ±ÎŽÎčÎșÎź ÎșÎ»ÎźÏƒÎ·}}} other {{direction, select, Outgoing {ΕΟΔρχόΌΔΜη ÎșÎ»ÎźÏƒÎ·} other {ΕÎčσΔρχόΌΔΜη ÎșÎ»ÎźÏƒÎ·}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎșÎ»ÎźÏƒÎ·} Video {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·} Group {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎżÎŒÎ±ÎŽÎčÎșÎź ÎșÎ»ÎźÏƒÎ·} other {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎșÎ»ÎźÏƒÎ·}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎșÎ»ÎźÏƒÎ·} Video {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·} Group {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎżÎŒÎ±ÎŽÎčÎșÎź ÎșÎ»ÎźÏƒÎ·} other {Î‘ÎœÎ±Ï€ÎŹÎœÏ„Î·Ï„Î· ÎșÎ»ÎźÏƒÎ·}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Î‘Ï€ÎżÏÏÎŻÏ†ÎžÎ·ÎșΔ ÎŒÎčα ÎșÎ»ÎźÏƒÎ·} Video {Î‘Ï€ÎżÏÏÎŻÏ†ÎžÎ·ÎșΔ ÎŒÎčα ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ·} Group {Î‘Ï€ÎżÏÏÎŻÏ†ÎžÎ·ÎșΔ ÎŒÎčα ÎżÎŒÎ±ÎŽÎčÎșÎź ÎșÎ»ÎźÏƒÎ·} other {Î‘Ï€ÎżÏÏÎŻÏ†ÎžÎ·ÎșΔ ÎŒÎčα ÎșÎ»ÎźÏƒÎ·}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} Ώλλο ÎŹÏ„ÎżÎŒÎż πληÎșÏ„ÏÎżÎ»ÎżÎłÎ”ÎŻ.} other {{count,number} Ώλλα ÎŹÏ„ÎżÎŒÎ± πληÎșÏ„ÏÎżÎ»ÎżÎłÎżÏÎœ.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ΝέΔς ΎυΜατότητΔς", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ΜÎčÎșρές Ï„ÏÎżÏ€ÎżÏ€ÎżÎčÎźÏƒÎ”Îčς, ΔπÎčÎŽÎčÎżÏÎžÏŽÏƒÎ”Îčς ÏƒÏ†Î±Î»ÎŒÎŹÏ„Ï‰Îœ ÎșαÎč ÎČΔλτÎčώσΔÎčς Î±Ï€ÏŒÎŽÎżÏƒÎ·Ï‚. ΕυχαρÎčÏƒÏ„ÎżÏÎŒÎ” Ï€ÎżÏ… χρησÎčÎŒÎżÏ€ÎżÎčÎ”ÎŻÏ‚ Ï„Îż Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Î‘Ï…Ï„Îź η ΔΜηΌέρωση πΔρÎčλαΌÎČÎŹÎœÎ”Îč ΌΔρÎčÎșές ÎČΔλτÎčώσΔÎčς ÎłÎčα φωΜητÎčÎșές ÎșÎ»ÎźÏƒÎ”Îčς ÎșαÎč ÎČÎčÎœÏ„Î”ÎżÎșÎ»ÎźÏƒÎ”Îčς, ÎșαΞώς ÎșαÎč ÎżÏÎčσΌέΜΔς ÎŒÎčÎșρές ΔΜηΌΔρώσΔÎčς τΔÎșÎŒÎ·ÏÎŻÏ‰ÏƒÎ·Ï‚ (ΔυχαρÎčÏƒÏ„ÎżÏÎŒÎ”, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "΀ώρα ÎŒÏ€ÎżÏÎ”ÎŻÏ‚ Μα Î±Î»Î»ÎŹÎŸÎ”Îčς τηΜ ΔπÎčÎ»Î”ÎłÎŒÎ­ÎœÎ· ÎłÎ»ÏŽÏƒÏƒÎ± ÏƒÏ„Îż Signal Ï‡Ï‰ÏÎŻÏ‚ Μα Î±Î»Î»ÎŹÎŸÎ”Îčς τÎčς ÏÏ…ÎžÎŒÎŻÏƒÎ”Îčς Ï„ÎżÏ… ÏƒÏ…ÏƒÏ„ÎźÎŒÎ±Ï„ÏŒÏ‚ ÏƒÎżÏ… (ÎĄÏ…ÎžÎŒÎŻÏƒÎ”Îčς Signal > Î•ÎŒÏ†ÎŹÎœÎčση > Γλώσσα)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ΕΜηΌΔρώσαΌΔ ÎżÏÎčσΌέΜα ΔÎčÎșÎżÎœÎŻÎŽÎčα ΔÎčÎŽÎżÏ€ÎżÎčÎźÏƒÎ”Ï‰Îœ ÎżÎŒÎŹÎŽÎ±Ï‚. Î‘Ï…Ï„ÎŹ τα ΔÎčÎșÎżÎœÎŻÎŽÎčα συΌÎČÎŹÎ»Î»ÎżÏ…Îœ στη ÎČÎ”Î»Ï„ÎŻÏ‰ÏƒÎ· της Î±ÎœÎ±ÎłÎœÏ‰ÏƒÎčΌότητας, ΔÎčÎŽÎčÎșÎŹ αΜ ζΔÎčς ÏƒÏ„Îż σÎșÎżÏ„ÎŹÎŽÎč Ï„ÎżÏ… ÎŁÎșÎżÏ„Î”ÎčÎœÎżÏ ÎžÎ­ÎŒÎ±Ï„ÎżÏ‚. ΀α Ï€ÏÎżÎ·ÎłÎżÏÎŒÎ”ÎœÎ± ΔÎčÎșÎżÎœÎŻÎŽÎčα απλώς Ï€ÏÎżÏƒÎ±ÏÎŒÏŒÎ¶ÎżÎœÏ„Î±Îœ ÏƒÏ„Îż σÎșÎżÏÏÎż. Î‘Ï…Ï„ÎŹ τα Μέα ΔÎčÎșÎżÎœÎŻÎŽÎčα ÎłÎ”ÎœÎœÎźÎžÎ·ÎșαΜ ÎșαÎč ÎŽÎčÎ±ÎŒÎżÏÏ†ÏŽÎžÎ·ÎșαΜ από Ï„Îż σÎșÎżÏ„ÎŹÎŽÎč." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ΔÎčÎżÏÎžÏŽÏƒÎ±ÎŒÎ” ÎŒÎčα ÎŒÎčÎșÏÎź ÎșαΞυστέρηση Ï€ÎżÏ… Ï…Ï€ÎźÏÏ‡Î” ΌΔρÎčÎșές Ï†ÎżÏÎ­Ï‚ ÎșÎ±Ï„ÎŹ τη ÏƒÏ…ÎŒÎŒÎ”Ï„ÎżÏ‡Îź σΔ ÎżÎŒÎ±ÎŽÎčÎșές ÎșÎ»ÎźÏƒÎ”Îčς σΔ συσÎșΔυές macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ΔÎčÎżÏÎžÏŽÏƒÎ±ÎŒÎ” τη ÎŒÎ”Ï„ÎŹÎČαση ΌΔ ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ”Ï‚ ΔÎčÎșόΜΔς ÎłÎčα πλαÎșÎŻÎŽÎčα ÎČÎŻÎœÏ„Î”Îż όταΜ ÎșÎŹÏ€ÎżÎčÎż ÎŹÏ„ÎżÎŒÎż συΌΌΔτέχΔÎč Îź Î±Ï€ÎżÏ‡Ï‰ÏÎ”ÎŻ από ÎŒÎčα ÎżÎŒÎ±ÎŽÎčÎșÎź ÎșÎ»ÎźÏƒÎ·." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "΀ώρα ÎŒÏ€ÎżÏÎ”ÎŻÏ‚ Μα Ï€Î±Ï„ÎźÏƒÎ”Îčς σΔ ÎŒÎčα Ï†Ï‰Ï„ÎżÎłÏÎ±Ï†ÎŻÎ± Ï€ÏÎżÏ†ÎŻÎ» Îź έΜα avatar ÎżÎŒÎŹÎŽÎ±Ï‚ στηΜ ÎșÎ”Ï†Î±Î»ÎŻÎŽÎ± της ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ±Ï‚ ÎłÎčα ÎłÏÎźÎłÎżÏÎ· πρόσÎČαση στÎčς ÏÏ…ÎžÎŒÎŻÏƒÎ”Îčς ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ±Ï‚ Îź ÎłÎčα Μα ΎΔÎčς τυχόΜ ÎčÏƒÏ„ÎżÏÎŻÎ”Ï‚ Ï€ÎżÏ… ΎΔΜ έχΔÎčς ΎΔÎč από Î±Ï…Ï„Îź τη ÏƒÏ…ÎœÎżÎŒÎčλία. ΕυχαρÎčÏƒÏ„ÎżÏÎŒÎ”, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/en/messages.json b/_locales/en/messages.json index cc564a6297..de23e72c84 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -109,11 +109,27 @@ }, "icu:databaseError": { "messageformat": "Database Error", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "A database error occurred. You can copy the error and contact Signal support to help fix the issue. If you need to use Signal right away, you can delete your data and restart.\n\nContact support by visiting: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Delete all data and restart", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Delete data and restart", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Permanently delete all data?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "All of your message history and media will be permanently deleted from this device. You will be able to use Signal on this device after relinking it. This will not delete any data from your phone.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "The version of your database does not match this version of Signal. Make sure you are opening the newest version of Signal on your computer.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&File", @@ -299,6 +315,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Something went wrong with your username, it’s no longer assigned to your account. You can try and set it again or choose a new one.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Fix now", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Something went wrong with your QR code and username link, it’s no longer valid. Create a new link to share with others.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Fix now", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Show Tabs", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Hide Tabs", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "An error occurred", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count, number} unread", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marked unread", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Calls", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Settings", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Update Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profile", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Back", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "These chats are archived and will only appear in the Inbox if new messages are received.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -575,6 +655,10 @@ "messageformat": "Call anyway", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Join anyway", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continue Call", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -636,23 +720,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Safety numbers are being updated.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Learn more", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Previous Safety number", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Next Safety number", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Safety number version, {index, number} of {total, number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Mark as verified", @@ -662,33 +746,41 @@ "messageformat": "Clear verification", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "To verify end-to-end encryption with {name}, compare the numbers above with their device. They can also scan your code with their device.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Learn more", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "To verify end-to-end encryption with {name}, match the color card above with their device and compare the numbers. If these don’t match, try the other pair of safety numbers. Only one pair needs to match.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "To verify end-to-end encryption with {name}, compare the numbers above with their device. They can also scan your code with their device.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Changes to safety numbers", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Safety numbers are being updated over a transition period to enable upcoming privacy features in Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "To verify safety numbers, match the color card with your contact’s device. If these don’t match, try the other pair of safety numbers. Only one pair needs to match.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Need help?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Got it", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "A safety number will be created with this person after you exchange messages with them.", @@ -1266,10 +1358,6 @@ "messageformat": "View recent media", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "To verify the security of your end-to-end encryption with {name}, compare the numbers above with their device. They can also scan the qr code above.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "You haven't exchanged any messages with this contact yet. Your safety number with them will be available after the first message." }, @@ -1333,21 +1421,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Delete", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Delete messages", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:deleteConversationConfirmation": { - "messageformat": "Permanently delete this chat?", - "description": "(deleted 06/27/2023) Confirmation dialog text that asks the user if they really wish to delete the conversation. Answer buttons use the strings 'ok' and 'cancel'. The deletion is permanent, i.e. it cannot be undone." + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Delete messages?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Delete chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" - }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "This chat will be deleted from this device.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Messages in this chat will be deleted from this device. You can still search for this chat after you delete messages.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Leave group", @@ -1441,6 +1525,14 @@ "messageformat": "Your message history for both chats have been merged here.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} belongs to {conversationTitle}. You're both members of {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} belongs to {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Thumbnail of image from quoted message", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1588,10 +1680,6 @@ "messageformat": "Call Again", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Start Call", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Join Call", "description": "Button label in the call lobby for joining a call" @@ -1604,13 +1692,25 @@ "messageformat": "Microphone muted due to the size of the call", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Call notifications", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Call is full", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Camera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Join", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Start", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Call full", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Camera disabled", @@ -1624,10 +1724,6 @@ "messageformat": "Turn on camera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Mute", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microphone disabled", "description": "Button tooltip label when the microphone is disabled" @@ -1640,10 +1736,6 @@ "messageformat": "Unmute mic", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Share", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Presenting disabled", "description": "Button tooltip label for when screen sharing is disabled" @@ -1656,10 +1748,6 @@ "messageformat": "Stop presenting", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ring", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Group is too large to ring the participants.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1672,6 +1760,26 @@ "messageformat": "Enable ringing", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Turn off ringing", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Turn on ringing", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "More options", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "Raised hands · {count, plural, one {# person} other {# people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "You", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Your camera is off", "description": "Label in the calling lobby indicating that your camera is off" @@ -2150,6 +2258,10 @@ "messageformat": "View Safety Number", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Message", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "View Safety Number", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2238,8 +2350,8 @@ "messageformat": "Failed to fetch phone number. Check your connection and try again.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Edits can only be applied within 3 hours from the time you sent this message.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Edits can only be applied within 24 hours from the time you sent this message.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2483,6 +2595,14 @@ "messageformat": "This message was deleted.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Attachment too large to display.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Some attachments are too large to display.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Unable to fetch donation details", "description": "Aria label for donation when we can't fetch the details." @@ -3125,10 +3245,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal beta only", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Editing messages is available to Signal beta users only. If you edit a message, it will only be visible to people who are on the latest version of Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Edit Message", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "If you edit a message, it will only be visible to people who are on the latest versions of Signal. They will be able to see you edited a message.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3383,6 +3511,14 @@ "messageformat": "Incoming video call...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Outgoing voice call", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Outgoing video call", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} is calling you", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3427,9 +3563,69 @@ "messageformat": "Reconnecting...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {# person} other {# people}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio call", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "End", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Leave", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mic off", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mic on", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Ringing on", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Ringing off", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount, number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Settings", @@ -3471,13 +3667,25 @@ "messageformat": "Fullscreen call", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Switch to grid view", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Change view", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Switch to speaker view", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Grid view", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Sidebar view", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Speaker view", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "View updated", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Leave call", @@ -3579,6 +3787,14 @@ "messageformat": "Okay", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Can't edit message", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Only {max, number} edits can be applied to this message.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Sorry, that sgnl:// link didn't make sense!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5255,10 +5471,30 @@ "messageformat": "Username", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Something went wrong with your username, it’s no longer assigned to your account.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Delete username", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Create username", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR code or link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Username needs reset", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Username link needs reset", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Share your username", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5323,10 +5559,6 @@ "messageformat": "Delete username", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "This will remove your username, allowing other users to claim it. Are you sure?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "This will remove your username and disable your QR code and link. “{username}” will be available for others to claim. Are you sure?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5615,6 +5847,42 @@ "messageformat": "You will no longer be able to share or view stories. Story updates you have recently shared will also be deleted.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Language", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Language", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "System Language", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Search languages", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "No results for “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Set", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Restart Signal to apply", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "To change the language, the app needs to restart.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Restart", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Update to version {version} available", "description": "Tooltip for new update available" @@ -5699,6 +5967,10 @@ "messageformat": "There was an error when saving your settings. Please try again.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Message", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "More styles", "description": "Action button for switching up the clock styles" @@ -6535,6 +6807,10 @@ "messageformat": "Reset", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Done", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Username link color, {index, number} of {total, number}", "description": "ARIA label of button for selecting username link color" @@ -6543,6 +6819,14 @@ "messageformat": "If you reset your QR code, your existing QR code and link will no longer work.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Resetting link...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR code and link not set. Check your network connection and try again.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Set up your Signal username", "description": "Title of username onboarding modal" @@ -6595,6 +6879,114 @@ "messageformat": "Send again", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "More actions", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Calls", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "New Call", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "New Call", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "More actions", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Clear call history", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Clear call history?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "This will permanently delete all call history", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Clear", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Call history cleared", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Click to view or start a call", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Search", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filter by missed", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Toggle", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "No recent calls. Get started by calling a friend.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "No results for “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Incoming", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Outgoing", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Missed", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Group call", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "No recent conversations.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "No results for “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{direction, select, Outgoing {Outgoing} other {Incoming}} {type, select, Audio {voice} Video {video} Group {group} other {}} call", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "Missed {type, select, Audio {voice} Video {video} Group {group} other {}} call", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "Unanswered {type, select, Audio {voice} Video {video} Group {group} other {}} call", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "Declined {type, select, Audio {voice} Video {video} Group {group} other {}} call", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {# other is} other {# others are}} typing.", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "What's New", "description": "Title for the whats new modal" @@ -6627,13 +7019,22 @@ "messageformat": "Small tweaks, bug fixes, and performance enhancements. Thanks for using Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "We modified the notification icons that appear for group updates, like when someone new joins a group. These icons help improve legibility, especially if you live within the darkness of the Dark Theme. The previous icons merely adopted the dark. The new icons were born in it, molded by it." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Now you can change your selected language in Signal without changing your system settings (Signal Settings > Appearance > Language)." }, - "icu:WhatsNew__v6.29--0": { - "messageformat": "The Chat Color customization screen is now displayed correctly across different languages and selected locales." + "icu:WhatsNew__v6.39--1": { + "messageformat": "We fixed a brief delay that sometimes occurred while joining a call lobby on macOS devices, which should get rid of at least one excuse for being a half-second late to the meeting." }, - "icu:WhatsNew__v6.29--1": { - "messageformat": "We improved notification support on Windows. If you don't click on a notification when it first arrives, the latest missed notification will appear in the Windows Notification Center. Clicking on that notification will now jump directly to that chat. We'd like to thank Julien Richard for their feedback." + "icu:WhatsNew__v6.41--0": { + "messageformat": "We fixed the transition animation for video tiles when someone joins or leaves a group call. When you see a friend's face slide into view, that's a social movement." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Now you can click on a profile photo or group avatar in the chat header to quickly access chat settings or view any unseen stories from that chat. Thanks, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/es/messages.json b/_locales/es/messages.json index 574eeefd43..bff013e388 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Fallo en la base de datos", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Se produjo un error en la base de datos. Puedes copiar el error y ponerte en contacto con el soporte de Signal para ayudar a solucionar el problema. Si necesitas utilizar Signal de inmediato, puedes eliminar tus datos y reiniciar.\n\nPonte en contacto con el servicio de soporte: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Borrar todos los datos y reiniciar", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Borrar los datos y reiniciar", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ÂżEliminar permanentemente todos los datos?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Todo tu historial de mensajes y archivos multimedia se eliminarĂĄn permanentemente de este dispositivo. PodrĂĄs utilizar Signal en este dispositivo despuĂ©s de volver a vincularlo. Esto no eliminarĂĄ ningĂșn dato de tu telĂ©fono.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "La versiĂłn de tu base de datos no coincide con esta versiĂłn de Signal. AsegĂșrate de abrir la versiĂłn mĂĄs reciente de Signal en tu ordenador.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Archivo", @@ -300,6 +316,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Ha habido un problema con tu alias; ya no estĂĄ asignado a tu cuenta. Puedes intentar configurarlo de nuevo o elegir uno distinto.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Reparalo ahora", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Hubo un problema con el cĂłdigo QR y el enlace de tu alias; ya no es vĂĄlido. Crea un nuevo enlace para compartir.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Reparalo ahora", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Mostrar pestañas", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ocultar pestañas", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ha habido un error", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} sin leer", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marcado como no leĂ­do", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Llamadas", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Historias", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Ajustes", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Actualizar Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Perfil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "AtrĂĄs", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Los chats archivados regresan a la lista principal si recibes mensajes nuevos.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Llamar de todas formas", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Unirme de todos modos", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continuar llamada", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Actualizaciones en los nĂșmeros de seguridad.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Saber mĂĄs", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "NĂșmero de seguridad anterior", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "NĂșmero de seguridad siguiente", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "VersiĂłn de nĂșmero de seguridad {index,number} de {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marcar persona como verificada", @@ -663,33 +747,41 @@ "messageformat": "Retirar marca de verificaciĂłn", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Para verificar el cifrado con {name}, compara las cifras de arriba con las del dispositivo de esa persona. TambiĂ©n puede escanear tu cĂłdigo con su dispositivo.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Saber mĂĄs", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Para verificar el cifrado con {name}, elige la carta de color que coincida con la del dispositivo de esa persona y compara las cifras. Si no coinciden, prueba con otro par de nĂșmeros de seguridad. Solo necesitas que coincida un par.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Para verificar el cifrado con {name}, compara las cifras de arriba con las del dispositivo de esa persona. TambiĂ©n puede escanear tu cĂłdigo con su dispositivo.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Cambios en los nĂșmeros de seguridad", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Se estĂĄn actualizando los nĂșmeros de seguridad durante un perĂ­odo de transiciĂłn para habilitar las prĂłximas funciones de privacidad en Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Para verificar los nĂșmeros de seguridad, haz que tu tarjeta de color coincida con la del dispositivo de tu contacto. Si no coinciden, prueba con otro par de nĂșmeros de seguridad. Solo necesitas que coincida un par.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ÂżNecesitas ayuda?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Entendido", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Se crearĂĄ un nĂșmero de seguridad con esta persona una vez intercambien mensajes.", @@ -1267,10 +1359,6 @@ "messageformat": "Ver archivos adjuntos recientes", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Para verificar la seguridad del cifrado de extremo a extremo con {name}, compara las cifras de arriba con las cifras presentes en su dispositivo. TambiĂ©n puede escanear el cĂłdigo QR de arriba.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "No has intercambiado ningĂșn mensaje con esta persona. Vuestras cifras de seguridad estarĂĄn disponibles despuĂ©s de enviar el primer mensaje." }, @@ -1334,17 +1422,17 @@ "messageformat": "Detalles", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Eliminar", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Eliminar mensajes", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ÂżEliminar chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ÂżEliminar mensajes?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Este chat se eliminarĂĄ de este dispositivo.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Los mensajes de este chat se eliminarĂĄn de este dispositivo. AĂșn podrĂĄs buscar este chat despuĂ©s de eliminar los mensajes.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Abandonar grupo", @@ -1438,6 +1526,14 @@ "messageformat": "Tu historial de mensajes para ambos chats se ha combinado aquĂ­.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pertenece a {conversationTitle}. Ambos son miembros de {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pertenece a {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura de imagen en mensaje citado", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Llamar de nuevo", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Iniciar llamada", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Unirse", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "MicrĂłfono silenciado en llamada de grupo numerosa", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Notificaciones de llamadas", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "La llamada estĂĄ llena", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "CĂĄmara", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Unirse", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Comenzar", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Llamada completa", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "CĂĄmara desactivada", @@ -1621,10 +1725,6 @@ "messageformat": "Activar cĂĄmara", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silenciar", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "MicrĂłfono desactivado", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Activar micrĂłfono", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Compartir", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PresentaciĂłn desactivada", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Terminar presentaciĂłn", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Llamar", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "El grupo es demasiado grande para notificar a tod@s l@s participantes.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Sonar como llamada entrante", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Desactivar el sonido", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Activar el sonido", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "MĂĄs opciones", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "TĂș", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Tu cĂĄmara estĂĄ desactivada", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Ver cifras de seguridad", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mensaje", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Ver cifras de seguridad", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Fallo al recuperar el nĂșm. de telĂ©fono. Comprueba tu conexiĂłn e intĂ©ntalo de nuevo.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Solo pueden hacerse cambios hasta 3 horas despuĂ©s del momento en que enviaste este mensaje.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Solo pueden hacerse cambios hasta 24 horas despuĂ©s del momento en que enviaste este mensaje.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Mensaje eliminado.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Archivo adjunto demasiado grande para mostrarlo.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Algunos archivos adjuntos son demasiado grandes para mostrarlos.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Fallo al recuperar los detalles de la donaciĂłn", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Solo para la versiĂłn beta de Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "La funciĂłn de ediciĂłn de mensajes solo estĂĄ disponible para las personas que tengan la versiĂłn beta de Signal. Si editas un mensaje, solo serĂĄ visible para las personas que tengan la Ășltima versiĂłn de Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editar mensaje", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Si editas un mensaje, solo serĂĄ visible para las personas que tengan las Ășltimas versiones de Signal. PodrĂĄn ver que has editado un mensaje.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Videollemada entrante
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Llamada realizada", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Videollamada realizada", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "Llamada de {ringer}", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Volviendo a conectar
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} persona} other {{count,number} personas}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Llamada", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Finalizar", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Abandonar", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "MicrĂłfono apagado", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "MicrĂłfono encendido", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Sonido activado", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Sonido desactivado", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Ajustes", @@ -3468,13 +3668,25 @@ "messageformat": "Llamada a pantalla completa", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Cambiar a vista de rejilla", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Cambiar la vista", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Cambiar a vista de persona activa", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Vista en cuadrĂ­cula", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Vista con barra lateral", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Ver solo al orador", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Vista actualizada", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Abandonar llamada", @@ -3576,6 +3788,14 @@ "messageformat": "De acuerdo", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "No se puede editar el mensaje", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Solo se puede hacer {max,number} cambio en este mensaje de texto.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Lo sentimos, ese enlace sgnl:// no es vĂĄlido.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Alias", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Ha habido un problema con tu alias; ya no estĂĄ asignado a tu cuenta.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Eliminar alias (nombre de usuarix)", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Crear alias (nombre de usuari@)", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "CĂłdigo QR o enlace", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "El alias necesita restablecerse", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Es necesario restablecer el enlace del alias", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Comparte tu alias", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Eliminar alias (nombre de usuarix)", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Esto eliminarĂĄ tu alias, permitiendo a otra persona usarlo. ÂżEstĂĄs segurx?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Esto eliminarĂĄ tu alias y deshabilitarĂĄ tu cĂłdigo QR y tu enlace. \"{username}\" estarĂĄ disponible para que otras personas lo usen. ÂżSeguro que quieres hacer esto?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Ya no podrĂĄs compartir o ver historias. Las historias que hayas compartido recientemente tambiĂ©n serĂĄn eliminadas.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Idioma", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Idioma", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Idioma del sistema", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Buscar idiomas", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "No se encontraron resultados para «{searchTerm}»", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Establecer", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Reiniciar Signal para aplicar cambios", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Para cambiar el idioma, la app debe reiniciarse.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Reiniciar", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "La actualizaciĂłn a la versiĂłn {version} estĂĄ disponible", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Ha ocurrido un fallo al guardar tus ajustes. Por favor, intĂ©ntalo de nuevo.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mensaje", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "MĂĄs estilos", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Reiniciar", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Hecho", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Color del enlace del alias, {index,number} de {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Si restableces tu cĂłdigo QR, tu cĂłdigo QR y tu enlace actuales dejarĂĄn de funcionar.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Restableciendo enlace
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "CĂłdigo QR y enlace no establecidos. Comprueba tu conexiĂłn y vuelve a intentarlo.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Configura tu alias de Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editado", + "messageformat": "Editado", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Enviar de nuevo", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "MĂĄs acciones", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Llamadas", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nueva llamada", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nueva llamada", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "MĂĄs acciones", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Eliminar historial de llamadas", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ÂżEliminar historial de llamadas?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Esto eliminarĂĄ permanentemente todo tu historial de llamadas", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Eliminar", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Se borrĂł el historial de llamadas", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Haz clic para ver o empezar una llamada", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Buscar", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrar por perdidas", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Mostrar", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "No hay llamadas recientes. Empieza llamando a alguien.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "No se encontraron resultados para «{query}»", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Entrante", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Saliente", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Perdida", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Llamada en grupo", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "No hay conversaciones recientes.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "No se encontraron resultados para «{query}»", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Llamada realizada} other {Llamada entrante}}} Video {{direction, select, Outgoing {Videollamada realizada} other {Videollamada entrante}}} Group {{direction, select, Outgoing {Llamada grupal realizada} other {Llamada grupal entrante}}} other {{direction, select, Outgoing {Realizando llamada} other {Recibiendo llamada}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Llamada perdida} Video {Videollamada perdida} Group {Llamada grupal perdida} other {Llamada perdida}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Llamada no atendida} Video {Videollamada no atendida} Group {Llamada de grupo no atendida} other {Llamada no atendida}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Llamada de voz rechazada} Video {Videollamada rechazada} Group {Llamada de grupo rechazada} other {Llamada rechazada}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} persona mĂĄs estĂĄ escribiendo.} other {{count,number} personas mĂĄs estĂĄn escribiendo.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Novedades", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Pequeños ajustes, soluciones a errores y mejoras al desempeño. ÂĄGracias por usar Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Esta actualizaciĂłn incluye algunas mejoras para llamadas de voz y vĂ­deo, y algunas actualizaciones menores de documentaciĂłn (ÂĄgracias, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Ahora puedes cambiar el idioma seleccionado en Signal sin cambiar los ajustes de tu sistema (Ajustes de Signal > Apariencia > Idioma)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Hemos modificado algunos de los los iconos de notificaciones de grupos." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Hemos solucionado un pequeño retraso que a veces ocurrĂ­a al unirse a una sala de llamadas en dispositivos macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Hemos arreglado la animaciĂłn de transiciĂłn de los mosaicos de vĂ­deo cuando alguien se une o abandona una llamada grupal." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Ahora puedes hacer clic en una foto de perfil o avatar de grupo en la cabecera del chat para acceder rĂĄpidamente a los ajustes del chat o ver cualquier historia que tengas pendiente de ese chat. ÂĄGracias, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/et-EE/messages.json b/_locales/et-EE/messages.json index 9d3e81195b..42046955f5 100644 --- a/_locales/et-EE/messages.json +++ b/_locales/et-EE/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Andmebaasi tĂ”rge", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Tekkis andmebaasi viga. Saad vea kopeerida ja Signali kasutajatoega ĂŒhendust vĂ”tta, et probleem lahendada. Kui sul on vaja Signalit kohe kasutada, saad oma andmed kustutada ja taaskĂ€ivitada.\n\nKasutajatoega saad ĂŒhendust vĂ”tta aadressil {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Kustuta kĂ”ik andmed ja taaskĂ€ivita", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Kustuta andmed ja taaskĂ€ivita", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Kas kustutada jÀÀdavalt kĂ”ik andmed?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Kogu sinu sĂ”numiajalugu ja meedia kustutatakse sellest seadmest jÀÀdavalt. Saad Signalit selles seadmes kasutada, kui selle taasĂŒhendad. Selle kĂ€igus ei kustutata andmeid sinu telefonist.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Sinu andmebaasi versioon ei klapi selle Signali versiooniga. Veendu, et avasid oma arvutis uusima Signali versiooni.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fail", @@ -300,6 +316,70 @@ "messageformat": "Vestlused", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Sinu kasutajanimega seoses lĂ€ks midagi valesti ja see ei ole enam sinu kontoga seotud. Saad proovida seda uuesti seadistada vĂ”i valida uue.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Paranda", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Midagi lĂ€ks sinu QR-koodi ja kasutajanime lingiga valesti ning see ei kehti enam. Loo teistega jagamiseks uus link.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Paranda", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Kuva vahekaardid", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Peida vahekaardid", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Tekkis viga", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} lugemata", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Mitteloetuks mĂ€rgitud", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Vestlused", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "KĂ”ned", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Lood", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "SĂ€tted", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Uuenda Signalit", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profiil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Tagasi", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Need vestlused on arhiveeritud ja ilmuvad sisendkausta ainult siis, kui saabub uusi sĂ”numeid.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Helista siiski", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Liitu siiski", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "KĂ”nega jĂ€tkamine", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Turvanumbreid uuendatakse.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Rohkem infot", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Eelmine turvanumber", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "JĂ€rgmine turvanumber", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Turvanumbri versioon, {index,number} koguarvust {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "MĂ€rgi kinnitatuks", @@ -663,33 +747,41 @@ "messageformat": "TĂŒhista kontrollimine", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Kasutajaga {name} otspunktkrĂŒpteerimise kontrollimiseks vĂ”rdle ĂŒlalpool olevaid numbreid tema seadmes olevatega. VĂ”id ka paluda tal skannida oma seadmega sinu koodi.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Rohkem infot", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Selleks, et kontrollida otspunktkrĂŒpteerimist kasutajaga {name}, vĂ”rdle ĂŒlalolevat vĂ€rvikaarti ja numbreid tema seadmes olevatega. Kui need on erinevad, proovi teist turvanumbrite paari. Vaid ĂŒks paar peab omavahel klappima.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Kasutajaga {name} otspunktkrĂŒpteerimise kontrollimiseks vĂ”rdle ĂŒlalpool olevaid numbreid tema seadmes olevatega. VĂ”id ka paluda tal skannida oma seadmega sinu koodi.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Muudatused turvanumbrites", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Turvanumbreid uuendatakse ĂŒleminekuperioodi jooksul, et vĂ”imaldada Signali uusi privaatsusfunktsioone.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Turvanumbrite kontrollimiseks vĂ”rdle vĂ€rvikaarti oma kontakti seadmes olevaga. Kui need on erinevad, proovi teist turvanumbrite paari. Vaid ĂŒks paar peab omavahel klappima.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Kas vajad abi?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Sain aru", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "PĂ€rast seda, kui te omavahel sĂ”numeid vahetate, luuakse selle isikuga turvanumber.", @@ -1267,10 +1359,6 @@ "messageformat": "NĂ€ita hiljutist meediat", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Kasutajaga {name} suhtluse krĂŒpteerimise kontrollimiseks vĂ”rdle ĂŒlalpool olevaid numbreid tema seadme ekraanil olevatega. VĂ”id ka paluda tal skannida ĂŒlalpool toodud QR-koodi.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Sa ei ole selle kontaktiga veel ĂŒhtegi sĂ”numit vahetanud. Sinu turvanumber temaga tekib pĂ€rast esimest sĂ”numit." }, @@ -1334,17 +1422,17 @@ "messageformat": "Teave", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Kustuta", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Kustuta sĂ”numid", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Kas kustutada vestlus?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Kas kustutada sĂ”numid?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "See vestlus kustutatakse sellest seadmest.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Selle vestluse sĂ”numid kustutatakse sellest seadmest. Saad pĂ€rast sĂ”numite kustutamist endiselt seda vestlust otsida.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Lahku grupist", @@ -1438,6 +1526,14 @@ "messageformat": "Sinu mĂ”lema vestluse sĂ”numite ajalugu on siin liidetud.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} kuulub vestlusesse {conversationTitle}. Olete mĂ”lemad grupi {sharedGroup} liikmed.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} kuulub vestlusesse {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Tsiteeritud sĂ”numist pĂ€rit pildi pisipilt", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Helista uuesti", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Alusta kĂ”net", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Liitu kĂ”nega", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon on kĂ”ne suuruse tĂ”ttu vaigistatud", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "KĂ”neteavitused", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "KĂ”ne on tĂ€is", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kaamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Liitu", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Alusta", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "KĂ”ne on tĂ€is", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kaamera on keelatud", @@ -1621,10 +1725,6 @@ "messageformat": "Kaamera sisse", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Vaigista", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon on keelatud", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "LĂŒlita mikrofon sisse", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Jaga", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Esitlemine on keelatud", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "LĂ”peta esitlus", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Helista", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupp on liikmetele helistamiseks liiga suur.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Luba helistamine", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "LĂŒlita helin vĂ€lja", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "LĂŒlita helin sisse", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Rohkem valikuid", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Sina", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Sinu kaamera on vĂ€ljas", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "NĂ€ita turvanumbrit", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "SĂ”num", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "NĂ€ita turvanumbrit", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Telefoninumbriga ei saadud ĂŒhendust. Kontrolli oma ĂŒhendust ja proovi uuesti.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Muutmine on vĂ”imalik vaid 3 tunni jooksul alates sĂ”numi saatmisest.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Muutmine on vĂ”imalik vaid 24 tunni jooksul alates sĂ”numi saatmisest.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "See sĂ”num kustutati.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Manus on kuvamiseks liiga suur.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "MĂ”ned manused on kuvamiseks liiga suured.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Annetuse andmeid ei Ă”nnestunud saada", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Ainult Signal beeta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "SĂ”numeid saavad muuta ainult Signali beetakasutajad. Kui sĂ”numit muudad, on see nĂ€htav ainult inimestele, kellel on uusim Signali beetaversioon.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Muuda sĂ”numit", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Kui sĂ”numit muudad, on see nĂ€htav ainult inimestele, kellel on Signali uusimad versioonid. Nad nĂ€evad, et oled sĂ”numit muutnud.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Sissetulev videokĂ”ne
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "VĂ€ljuv hÀÀlkĂ”ne", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Tehtud videokĂ”ne", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} helistab sulle", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Ühenduse taastamine
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} inimene} other {{count,number} inimest}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "HÀÀlkĂ”ne", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "LĂ”peta", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Lahku", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon vĂ€ljas", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon sees", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Helin sees", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Helin vĂ€ljas", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "SĂ€tted", @@ -3468,13 +3668,25 @@ "messageformat": "TĂ€isekraanil kĂ”ne", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "LĂŒlita vĂ”rgustikuvaatele", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Muuda vaadet", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "LĂŒlita rÀÀkija vaatele", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Ruudustikvaade", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "KĂŒlgriba vaade", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "KĂ”neleja vaade", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Kuva uuendatud", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Lahku kĂ”nest", @@ -3576,6 +3788,14 @@ "messageformat": "Sobib", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "SĂ”numit ei saa muuta", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Seda sĂ”numit saab muuta ainult {max,number} korda.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Vabandust, see sgnl:// link ei ole arusaadav!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Kasutajanimi", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Sinu kasutajanimega seoses lĂ€ks midagi valesti ja see ei ole enam sinu kontoga seotud.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Eemalda kasutajanimi", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Loo kasutajanimi", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-kood vĂ”i link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Kasutajanimi tuleb lĂ€htestada", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Kasutajanime link tuleb lĂ€htestada", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Jaga oma kasutajanime", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Eemalda kasutajanimi", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "KĂ€esolevaga eemaldad oma kasutajanime ning keegi teine saab selle kasutusse vĂ”tta. Kas oled kindel?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Sellega eemaldad oma kasutajanime ning muudad QR-koodi ja lingi kehtetuks. Keegi teine saab nĂŒĂŒd kasutajanime „{username}“ omale vĂ”tta. Kas oled kindel?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Sa ei saa enam lugusid jagada ega vaadata. Sinu hiljuti jagatud lugude uuendused kustutatakse samuti.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Keel", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Keel", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "SĂŒsteemi keel", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Otsi keeli", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "„{searchTerm}“ ei andnud otsingutulemusi", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "MÀÀra", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "TaaskĂ€ivita Signal, et muudatused rakenduksid", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Keele vahetamiseks tuleb Ă€pp taaskĂ€ivitada.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "TaaskĂ€ivita", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Versioonile {version} on uuendus saadaval", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "SĂ€tete salvestamisel tekkis tĂ”rge. Palun proovi uuesti.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "SĂ”num", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Rohkem stiile", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "LĂ€htesta", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Tehtud", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Kasutajanime lingi vĂ€rv, {index,number} {total,number}-st", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Kui oma QR-koodi lĂ€htestad, lĂ”petavad olemasolev QR-kood ja link toimimise.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Lingi lĂ€htestamine 
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-kood ja link ei ole seadistatud. Kontrolli oma vĂ”rguĂŒhendust ja proovi uuesti.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Seadista oma Signali kasutajanimi", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "muudetud", + "messageformat": "Muudetud", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Saada uuesti", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Rohkem tegevusi", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "KĂ”ned", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Uus kĂ”ne", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Uus kĂ”ne", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Rohkem tegevusi", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "TĂŒhjenda kĂ”neajalugu", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Kas tĂŒhjendada kĂ”neajalugu?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "See kustutab jÀÀdavalt kogu kĂ”neajaloo", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Eemalda", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "KĂ”neajalugu on eemaldatud", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "KlĂ”psa, et kĂ”net nĂ€ha vĂ”i alustada", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Otsi", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtreeri vastamata kĂ”nede alusel", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "LĂŒlita", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Hiljutised kĂ”ned puuduvad. Tee ots lahti ja helista sĂ”brale.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "„{query}“ ei andnud otsingutulemusi", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Sissetulev", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "VĂ€ljuv", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Vastamata", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "GrupikĂ”ne", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Hiljutisi vestlusi pole.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "„{query}“ ei andnud otsingutulemusi", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {VĂ€ljuv hÀÀlkĂ”ne} other {Sissetulev hÀÀlkĂ”ne}}} Video {{direction, select, Outgoing {Tehtud videokĂ”ne} other {Sissetulev videokĂ”ne}}} Group {{direction, select, Outgoing {VĂ€ljuv grupikĂ”ne} other {Sissetulev grupikĂ”ne}}} other {{direction, select, Outgoing {VĂ€ljaminev kĂ”ne} other {Sissetulev kĂ”ne}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Vastamata hÀÀlkĂ”ne} Video {Vastamata videokĂ”ne} Group {Vastamata grupikĂ”ne} other {Vastamata kĂ”ne}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Vastamata hÀÀlkĂ”ne} Video {Vastamata videokĂ”ne} Group {Vastamata grupikĂ”ne} other {Vastamata kĂ”ne}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Sa keeldusid hÀÀlkĂ”nest} Video {Sa keeldusid videokĂ”nest} Group {Sa keeldusid grupikĂ”nest} other {Sa keeldusid kĂ”nest}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} veel kirjutab.} other {{count,number} veel kirjutavad.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Mis on uut", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "VĂ€ikesed muudatused, vigade parandused ja jĂ”udluse tĂ€iustused. AitĂ€h, et kasutad Signalit!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "See uuendus sisaldab mĂ”nesid hÀÀl- ja videokĂ”nede parendusi ning vĂ€ikesi uuendusi dokumentides (aitĂ€h, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "NĂŒĂŒd saad Signalis oma valitud keelt muuta ilma sĂŒsteemi sĂ€tteid muutmata (Signali sĂ€tted > VĂ€limus > Keel)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Muutsime mĂ”nesid grupi teavituste ikoone." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Parandasime kerge viivituse, mis mĂ”nikord macOS-i seadmetes kĂ”ne ooteruumiga liitumisel tekkis." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Parandasime Ă€ra videoakende ĂŒleminekuanimatsiooni, kui keegi grupivestlusega liitub vĂ”i sellest lahkub." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "NĂŒĂŒd saad klĂ”psata vestluse pĂ€ises profiilifotole vĂ”i grupi avatarile, et avada kiiresti vestluse sĂ€tted vĂ”i vaadata vestluses olevaid lugusid, mis sul nĂ€gemata on jÀÀnud. AitĂ€h, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/eu/messages.json b/_locales/eu/messages.json index 70571c833b..8d27b6ccff 100644 --- a/_locales/eu/messages.json +++ b/_locales/eu/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Datubasearen Errorea", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Datu-baseko errore bat gertatu da. Errorea kopiatu, eta Signal-en zerbitzu teknikoarekin harremanetan jar zaitezke, arazoa konpontzen lagun diezazuten. Signal berehala erabili behar baduzu, zure datuak ezabatu, eta berrabiarazi egin dezakezu.\n\nJarri harremanetan laguntza-zerbitzuarekin hemen: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Ezabatu datu guztiak eta berrabiarazi", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Ezabatu datuak eta berrabiarazi", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Datu guztiak behin betiko ezabatu nahi dituzu?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Zure mezuen historia eta multimedia-elementu guztiak betiko ezabatuko dira gailu honetatik. Gailu honetan Signal erabili ahal izateko, berriro lotu beharko duzu. Horrek ez du daturik ezabatuko telefonotik.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Zure datu-basearen bertsioa ez dator bat Signal-en bertsio honekin. Ziurtatu Signal-en bertsio berriena erabiltzen ari zarela ordenagailuan.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fitxategia", @@ -300,6 +316,70 @@ "messageformat": "Txatak", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Arazoren bat izan da erabiltzaile-izenarekin, eta jada ez dago kontuari esleitua. Berriro konfiguratu, edo beste bat aukera dezakezu.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Konpondu orain", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Arazoren bat izan da QR kodearekin edo erabiltzaile-izenaren estekarekin, eta jada ez du balio. Sortu jendearekin partekatzeko beste esteka bat.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Konpondu orain", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Erakutsi jakinarazpenak", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ezkutatu jakinarazpenak", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Akats bat gertatu da", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} irakurri gabe", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Irakurri gabeko gisa markatu da", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Txatak", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Deiak", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Istorioak", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Ezarpenak", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Eguneratu Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profila", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Atzera", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Txat hauek artxibatuta daude eta mezu berriak jasotzen badira soilik agertuko dira sarrera-ontzian.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Deitu edonola ere", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Sartu hala ere", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Deia jarraitu", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Segurtasun-zenbakiak eguneratzen.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Gehiago jakin", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Aurreko segurtasun-zenbakia", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Hurrengo segurtasun-zenbakia", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Segurtasun-zenbakiaren bertsioa, {index,number}/{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Markatu egiaztatutako gisa", @@ -663,33 +747,41 @@ "messageformat": "Garbitu egiaztapena", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} erabiltzailearekin muturretik muturrerako enkriptatzea egiaztatzeko, alderatu goiko zenbakiak haren gailukoekin. Halaber, zure kodea eskanea dezake bere gailuarekin.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Informazio gehiago", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} erabiltzailrarekin muturretik muturrerako enkriptatzea egiaztatzeko, lotu goiko kolore-txartela bere gailuarekin eta alderatu zenbakiak. Bat ez badatoz, saiatu beste segurtasun-zenbaki parearekin. Bikote bakarrak bat egin behar du.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} erabiltzailearekin muturretik muturrerako enkriptatzea egiaztatzeko, alderatu goiko zenbakiak haren gailukoekin. Halaber, zure kodea eskanea dezake bere gailuarekin.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Segurtasun-zenbakien aldaketak", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Segurtasun-zenbakiak trantsizio-aldi batean eguneratzen ari dira Signal-en datozen pribatutasun-eginbideak gaitzeko.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Segurtasun-zenbakiak egiaztatzeko, lotu kolore-txartela zure kontaktuaren gailuarekin. Bat ez badatoz, saiatu beste segurtasun-zenbaki parearekin. Bikote bakarrak bat egin behar du.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Laguntza behar duzu?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Ulertu dut", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Segurtasun-zenbaki bat sortuko da pertsona honekin mezuak trukatu ondoren.", @@ -1267,10 +1359,6 @@ "messageformat": "Ikusi arestiko medioak", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} erabiltzailearekin muturretik muturrerako enkriptatzearen segurtasuna egiaztatzeko, alderatu goiko zenbakiak haren gailukoekin. Halaber, goiko QR kodea eskanea dezake.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Oraindik ez duzu mezurik trukatu konkaktu honekin. Zure segurtasun zenbakia eskuragarri egongo da lehenengo mezua bidali ondoren." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Ezabatu", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Ezabatu mezuak", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Txata ezabatu nahi duzu?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Mezuak ezabatu nahi dituzu?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Txat hau gailu honetatik ezabatuko da.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Txat honetako mezuak gailu honetatik ezabatuko dira. Mezuak ezabatuta ere, txat hau bilatu ahalko duzu.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Irten taldetik", @@ -1438,6 +1526,14 @@ "messageformat": "Bi txatetako mezuen historiak hemen bateratu dira.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} erabiltzailearena da. Biak zarete {sharedGroup} taldeko kideak.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} erabiltzailearena da", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Aipatutako mezuaren miniatura edo irudia", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Deitu berriro", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Hasi Deia", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Deian Sartu", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Deiaren tamaina dela eta, mikrofonoa desaktibatuta dago", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Dei-jakinarazpenak", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Deia beteta dago", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Sartu", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Hasi", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Deia beteta dago", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamara desaktibatuta", @@ -1621,10 +1725,6 @@ "messageformat": "Piztu kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Desaktibatu jakinarazpenak", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofonoa desaktibatuta", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Aktibatu mikronofoa", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Partekatu", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Aurkezteko aukera desgaituta dago", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Utzi aurkezteari", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Deitu", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Taldea handiegia da parte-hartzaileei deitzeko.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Gaitu deitzeko aukera", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Desaktibatu dei-tonua", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Aktibatu dei-tonua", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Aukera gehiago", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Zu", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Zure kamera itzalita dago", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Erakutsi segurtasun-zenbakia", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mezua", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Erakutsi segurtasun-zenbakia", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Ezin izan da eskuratu telefono-zenbakia. Egiaztatu konektatuta zaudela eta saiatu berriro.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Mezu hau bidali eta 3 orduko epean soilik aplika daitezke aldaketak.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Mezu hau bidali eta 24 orduko epean soilik aplika daitezke aldaketak.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Mezu hau ezabatu egin da.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Eranskina handiegia da eta ezin da bistaratu.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Eranskin batzuk handiegiak dira eta ezin dira bistaratu.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Ezin dira eskuratu dohaintzaren xehetasunak", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal-en beta-bertsiorako soilik", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Signal-en beta-bertsioaren erabiltzaileek bakarrik edita ditzakete mezuak. Mezu bat editatzen baduzu, Signal-en beta-bertsio berriena darabilten pertsonek soilik ikusi ahalko dute.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editatu mezua", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Mezu bat editatzen baduzu, Signal-en azken bertsioak darabiltzaten pertsonek soilik izango dute ikusgai. Mezu bat editatu duzula ikusi ahal izango dute.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Sarrerako bideodeia", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Irteerako ahots-deia", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Irteerako bideodeia", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} deika duzu", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Berriro konektatzen
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {Pertsona {count,number}} other {{count,number} pertsona}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio-deia", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Amaitu", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Irten", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofonoa desaktibatuta", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofonoa aktibatuta", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Dei-tonua aktibatuta", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Dei-tonua desaktibatuta", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Ezarpenak", @@ -3468,13 +3668,25 @@ "messageformat": "Deia pantaila osoan jarri", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Aldatu saretutako bistara", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Aldatu ikuspegia", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Aldatu hizlariaren bistara", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Sareta ikuspegia", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Alboko barrako ikuspegia", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Hizlariaren ikuspegia", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Eguneratu da ikuspegia", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Deia utzi", @@ -3576,6 +3788,14 @@ "messageformat": "Ados", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Ezin da editatu mezua", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "{max,number} aldaketa bakarrik egin daitezke mezu honetan.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Barkatu, sgnl:// esteka hori ez da zuzena!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Erabiltzaile-izena", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Arazoren bat izan da erabiltzaile-izenarekin, eta jada ez dago kontuari esleitua.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Ezabatu erabiltzaile-izena", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Sortu erabiltzaile-izena", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kodea edo esteka", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Erabiltzaile-izena berrezarri egin behar da", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Erabiltzaile-izenaren esteka berrezarri egin behar da", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Partekatu zure erabiltzaile-izena", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Ezabatu erabiltzaile-izena", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Honen bidez, zure erabiltzaile-izena kenduko da, eta beste erabiltzaile batzuek eskatu ahal izango dute. Ziur zaude?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Erabiltzaile-izena kendu, eta QR kodea eta esteka desgaitu egingo dira. \"{username}\" beste norbaitek erabili ahalko du. Ziur zaude?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Aurrerantzean ezingo dituzu partekatu edo ikusi istorioak. Duela gutxi partekatu dituzun istorio-eguneratzeak ere ezabatuko dira.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Hizkuntza", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Hizkuntza", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistemaren hizkuntza", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Bilatu hizkuntza", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Ez dago honen emaitzarik: \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Ezarri", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Aplikatzeko, berrabiarazi Signal", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Hizkuntza aldatzeko, aplikazioa berrabiarazi behar da.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Berrabiarazi", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Eguneratu {version}eskuragarri dagoen bertsiora", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Errore bat gertatu da ezarpenak gordetzean. Saiatu berriro mesedez.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mezua", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Estilo gehiago", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Berrabiarazi", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Eginda", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Erabiltzaile-izenen esteken kolorea, {total,number} koloretatik {index,number}garrena", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "QR kodea berrezarriz gero, oraingo QR kodeak eta estekak funtzionatzeari utziko diote.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Esteka berrezartzen
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kodea eta esteka ez daude konfiguratuta. Egiaztatu sarera konektatuta zaudela eta saiatu berriro.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Konfiguratu Signal-eko erabiltzaile-izena", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editatuta", + "messageformat": "Editatua", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Berriro Bidali", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Ekintza gehiago", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Deiak", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Dei berria", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Dei berria", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Ekintza gehiago", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Garbitu deien historia", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Deien historia garbitu nahi duzu?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Behin betiko ezabatuko da deien historia osoa", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Garbitu", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Deien historia garbitu da", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Egin klik dei bat ikusteko edo hasteko", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Bilatu", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Iragazi dei galduen arabera", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Kommutatu", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ez dago azken deirik. Hasi lagun bati deitzen.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Ez dago honen emaitzarik: \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Sarrerako", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Irteerakoak", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Galduak", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Talde-deia", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ez dago duela gutxiko elkarrizketarik.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Ez dago honen emaitzarik: \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Irteerako ahots-deia} other {Sarrerako ahots-deia}}} Video {{direction, select, Outgoing {Irteerako bideodeia} other {Sarrerako bideodeia}}} Group {{direction, select, Outgoing {Irteerako talde-deia} other {Sarrerako talde-deia}}} other {{direction, select, Outgoing {Irteerako deia} other {Sarrerako dei}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Ahots-dei galdua} Video {Bideodei galdua} Group {Talde-deia galdua} other {Erantzun gabeko deia}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Erantzun gabeko ahots-deia} Video {Erantzun gabeo bideodeia} Group {Erantzun gabeko taldeko deia} other {Erantzun gabeko deia}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Ahots-deia baztertu da} Video {Bideodeia baztertu da} Group {Talde-deia baztertu da} other {Deia baztertu da}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {Beste {count,number} idazten ari da.} other {Beste {count,number} idazten ari dira.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Zer berri", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Doikuntza txikiak, akats-konponketak eta errendimendu-hobekuntzak. Eskerrik asko Signal erabiltzeagatik!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Eguneratze honek ahots- eta bideo-deietarako hobekuntza batzuk eta dokumentazio-eguneratze txiki batzuk ditu (eskerrik asko, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Orain, sistemaren ezarpenak aldatu beharrik gabe alda dezakezu Signal-en hizkuntza (Signal-en Ezarpenak > Itxura > Hizkuntza)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Taldeen jakinarazpen-ikono batzuk eguneratu ditugu, eta PUZa gainkarga zezakeen akats bat konpondu." + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOS gailuetan deien harrera-pantailara sartzean batzuetan gertatzen zen atzerapen laburra konpondu dugu." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Norbait taldeko dei batean sartzen denean edo hartatik irteten denean ikusten diren bideo-lauzen trantsizio-animazioa konpondu dugu. Lagun baten aurpegia agertzen denean, mugimendu soziala deritzo." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Orain, txat-ezarpenak bizkor atzitzeko edo txat horretan ikusi ez dituzun istorioak ikusteko, profileko argazkiak edo talde-abatarrak saka ditzakezu. Aupa zu, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/fa-IR/messages.json b/_locales/fa-IR/messages.json index ef5c950495..e2727e61ec 100644 --- a/_locales/fa-IR/messages.json +++ b/_locales/fa-IR/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ŰźŰ·Ű§ÛŒ ÙŸŰ§ÛŒÚŻŰ§Ù‡ ŰŻŰ§ŰŻÙ‡", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "یک ŰźŰ·Ű§ÛŒ ÙŸŰ§ÛŒÚŻŰ§Ù‡ ŰŻŰ§ŰŻÙ‡ ۱۟ ۯۧۯ. می‌ŰȘÙˆŰ§Ù†ÛŒŰŻ ۟۷ۧ ۱ۧ Ú©ÙŸÛŒ Ú©Ù†ÛŒŰŻ و ŰšŰ±Ű§ÛŒ کمک ŰšÙ‡ Ű±ÙŰč Ù…ŰŽÚ©Ù„ ۚۧ ÙŸŰŽŰȘÛŒŰšŰ§Ù†ÛŒ ŰłÛŒÚŻÙ†Ű§Ù„ ŰȘÙ…Ű§Űł ŰšÚŻÛŒŰ±ÛŒŰŻ. ۧگ۱ ÙÙˆŰ±Ű§Ù‹ Ù†ÛŒŰ§ŰČ ŰšÙ‡ ۧ۳ŰȘÙŰ§ŰŻÙ‡ ۧŰČ ŰłÛŒÚŻÙ†Ű§Ù„ ŰŻŰ§Ű±ÛŒŰŻŰŒ می‌ŰȘÙˆŰ§Ù†ÛŒŰŻ ŰŻŰ§ŰŻÙ‡â€ŒÙ‡Ű§ÛŒŰȘŰ§Ù† ۱ۧ ÙŸŰ§Ú© Ú©Ù†ÛŒŰŻ و ŰłÛŒÚŻÙ†Ű§Ù„ ۱ۧ ŰŻÙˆŰšŰ§Ű±Ù‡ Ű±Ű§Ù‡â€ŒŰ§Ù†ŰŻŰ§ŰČی Ú©Ù†ÛŒŰŻ.\n\nŰȘÙ…Ű§Űł ۚۧ ÙŸŰŽŰȘÛŒŰšŰ§Ù†ÛŒ ۧŰČ Ű·Ű±ÛŒÙ‚ Ù…Ű±Ű§ŰŹŰčه ŰšÙ‡: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† همه Ű§Ű·Ù„Ű§ŰčۧŰȘ و Ű±Ű§Ù‡â€ŒŰ§Ù†ŰŻŰ§ŰČی ŰŻÙˆŰšŰ§Ű±Ù‡", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† ŰŻŰ§ŰŻÙ‡â€ŒÙ‡Ű§ و Ű±Ű§Ù‡â€ŒŰ§Ù†ŰŻŰ§ŰČی Ù…ŰŹŰŻŰŻ", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "همه ŰŻŰ§ŰŻÙ‡â€ŒÙ‡Ű§ ŰšÙ‡â€ŒŰ·ÙˆŰ± ŰŻŰ§ŰŠÙ… ÙŸŰ§Ú© ŰŽÙˆŰŻŰŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "کل ŰȘŰ§Ű±ÛŒŰźÚ†Ù‡ ÙŸÛŒŰ§Ù… و Ű±ŰłŰ§Ù†Ù‡ ŰŽÙ…Ű§ ŰšÙ‡â€ŒŰ·ÙˆŰ± ŰŻŰ§ŰŠÙ… ۧŰČ Ű§ÛŒÙ† ŰŻŰłŰȘÚŻŰ§Ù‡ ÙŸŰ§Ú© ŰźÙˆŰ§Ù‡ŰŻ ŰŽŰŻ. ÙŸŰł ۧŰČ ÙŸÛŒÙˆÙ†ŰŻ ŰŻŰ§ŰŻÙ† Ù…ŰŹŰŻŰŻ ŰłÛŒÚŻÙ†Ű§Ù„ŰŒ Ù‚Ű§ŰŻŰ± ŰšÙ‡ ۧ۳ŰȘÙŰ§ŰŻÙ‡ ۧŰČ ŰąÙ† ۯ۱ Ű§ÛŒÙ† ŰŻŰłŰȘÚŻŰ§Ù‡ ŰźÙˆŰ§Ù‡ÛŒŰŻ ŰšÙˆŰŻ. Ű§ÛŒÙ† Ù…ÙˆŰŹŰš ÙŸŰ§Ú© ŰŽŰŻÙ† ŰŻŰ§ŰŻÙ‡â€ŒÙ‡Ű§ ۧŰČ ŰȘلفن ŰŽÙ…Ű§ Ù†Ù…ÛŒâ€ŒŰŽÙˆŰŻ.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Ù†ŰłŰźÙ‡ ÙŸŰ§ÛŒÚŻŰ§Ù‡ ŰŻŰ§ŰŻÙ‡ ŰŽÙ…Ű§ ۚۧ Ű§ÛŒÙ† Ù†ŰłŰźÙ‡ ŰłÛŒÚŻÙ†Ű§Ù„ Ù…Ű·Ű§ŰšÙ‚ŰȘ Ù†ŰŻŰ§Ű±ŰŻ. Ù…Ű·Ù…ŰŠÙ† ŰŽÙˆÛŒŰŻ که ŰŹŰŻÛŒŰŻŰȘŰ±ÛŒÙ† Ù†ŰłŰźÙ‡ ŰłÛŒÚŻÙ†Ű§Ù„ ۱ۧ ۯ۱ Ű±Ű§ÛŒŰ§Ù†Ù‡â€ŒŰȘŰ§Ù† ۚۧŰČ Ù…ÛŒâ€ŒÚ©Ù†ÛŒŰŻ.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ÙŰ§ÛŒÙ„", @@ -300,6 +316,70 @@ "messageformat": "ÚŻÙŰȘÚŻÙˆÙ‡Ű§", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ŰźŰ·Ű§ÛŒÛŒ ۯ۱ Ù…ÙˆŰ±ŰŻ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰŽÙ…Ű§ ۱۟ ۯۧۯی Ű§ÛŒÙ† Ù†Ű§Ù… ŰŻÛŒÚŻŰ± ŰšÙ‡ ۭ۳ۧۚ ŰŽÙ…Ű§ ŰȘŰčلق Ù†ŰŻŰ§Ű±ŰŻ. می‌ŰȘÙˆŰ§Ù†ÛŒŰŻ ŰłŰčی Ú©Ù†ÛŒŰŻ و ŰŻÙˆŰšŰ§Ű±Ù‡ ŰąÙ† ۱ۧ ۚ۱گŰČÛŒÙ†ÛŒŰŻ ÛŒŰ§ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰŹŰŻÛŒŰŻÛŒ Ű§Ù†ŰȘ۟ۧۚ Ú©Ù†ÛŒŰŻ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Ű§Ú©Ù†ÙˆÙ† Ű§Ű”Ù„Ű§Ű­ ŰŽÙˆŰŻ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ŰźŰ·Ű§ÛŒÛŒ ۯ۱ Ù…ÙˆŰ±ŰŻ Ú©ŰŻ QR و ÙŸÛŒÙˆÙ†ŰŻ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰŽÙ…Ű§ ۱۟ ۯۧۯ و ŰŻÛŒÚŻŰ± مŰčŰȘۚ۱ Ù†ÛŒŰłŰȘ. ÙŸÛŒÙˆÙ†ŰŻ ŰŹŰŻÛŒŰŻÛŒ Ű§ÛŒŰŹŰ§ŰŻ Ú©Ù†ÛŒŰŻ ŰȘۧ ۚۧ ŰŻÛŒÚŻŰ±Ű§Ù† ŰšÙ‡ ۧێŰȘ۱ۧک ŰšÚŻŰ°Ű§Ű±ÛŒŰŻ.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Ű§Ú©Ù†ÙˆÙ† Ű§Ű”Ù„Ű§Ű­ ŰŽÙˆŰŻ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Ù†Ù…Ű§ÛŒŰŽ ŰČŰšŰ§Ù†Ù‡â€ŒÙ‡Ű§", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ÙŸÙ†Ù‡Ű§Ù† Ú©Ű±ŰŻÙ† ŰČŰšŰ§Ù†Ù‡â€ŒÙ‡Ű§", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ŰźŰ·Ű§ÛŒÛŒ ۱۟ ۯۧۯ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ŰźÙˆŰ§Ù†ŰŻÙ‡â€ŒÙ†ŰŽŰŻÙ‡", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ŰčÙ„Ű§Ù…ŰȘâ€ŒÚŻŰ°Ű§Ű±ÛŒ ŰšÙ‡â€ŒŰčÙ†ÙˆŰ§Ù† ŰźÙˆŰ§Ù†ŰŻÙ‡â€ŒÙ†ŰŽŰŻÙ‡", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ÚŻÙŰȘÚŻÙˆÙ‡Ű§", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ŰȘÙ…Ű§Űłâ€ŒÙ‡Ű§", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ۧ۳ŰȘÙˆŰ±ÛŒâ€ŒÙ‡Ű§", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ŰȘÙ†ŰžÛŒÙ…Ű§ŰȘ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ ŰłÛŒÚŻÙ†Ű§Ù„", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ÙŸŰ±ÙˆÙŰ§ÛŒÙ„", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ۚۧŰČÚŻŰŽŰȘ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ű§ÛŒÙ† ÚŻÙŰȘÚŻÙˆÙ‡Ű§ ŰšŰ§ÛŒÚŻŰ§Ù†ÛŒ ŰŽŰŻÙ‡â€ŒŰ§Ù†ŰŻ و ŰȘÙ†Ù‡Ű§ ۯ۱ Ű”ÙˆŰ±ŰȘی ۯ۱ Ű”Ù†ŰŻÙˆÙ‚ ÙˆŰ±ÙˆŰŻÛŒ Ù†Ù…Ű§ÛŒŰŽ ŰŻŰ§ŰŻÙ‡ ŰźÙˆŰ§Ù‡Ù†ŰŻ ŰŽŰŻ که ÙŸÛŒŰ§Ù…â€ŒÙ‡Ű§ÛŒ ŰŹŰŻÛŒŰŻ ŰŻŰ±ÛŒŰ§ÙŰȘ ŰŽÙˆÙ†ŰŻ.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ۯ۱ Ù‡Ű± Ű”ÙˆŰ±ŰȘ ŰȘÙ…Ű§Űł ŰšÚŻÛŒŰ±", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ŰšÙ‡ Ù‡Ű± Ű­Ű§Ù„ Ù…ÛŒâ€ŒÙŸÛŒÙˆÙ†ŰŻÙ…", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Ű§ŰŻŰ§Ù…Ù‡ ŰȘÙ…Ű§Űł", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ…Ù†ÛŒ ۯ۱ Ű­Ű§Ù„ ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ Ù‡ŰłŰȘÙ†ŰŻ.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ŰšÛŒŰŽŰȘ۱ ÛŒŰ§ŰŻ ŰšÚŻÛŒŰ±ÛŒŰŻ", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ŰŽÙ…Ű§Ű±Û€ Ű§ÛŒÙ…Ù†ÛŒ Ù‚ŰšÙ„ÛŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ŰŽÙ…Ű§Ű±Û€ Ű§ÛŒÙ…Ù†ÛŒ ŰšŰčŰŻÛŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Ù†ŰłŰźÛ€ ŰŽÙ…Ű§Ű±Û€ Ű§ÛŒÙ…Ù†ÛŒŰŒ {index,number} ۧŰČ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ŰčÙ„Ű§Ù…ŰȘâ€ŒÚŻŰ°Ű§Ű±ÛŒ ŰšÙ‡ ŰčÙ†ÙˆŰ§Ù† ŰȘŰŁÛŒÛŒŰŻ ŰŽŰŻÙ‡", @@ -663,33 +747,41 @@ "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† ŰȘŰŁÛŒÛŒŰŻ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "ŰšŰ±Ű§ÛŒ ŰšŰ±Ű±ŰłÛŒ Ű±Ù…ŰČÚŻŰ°Ű§Ű±ÛŒ ۳۱ŰȘŰ§ŰłŰ±ÛŒ ۚۧ {name}ی ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ ŰšŰ§Ù„Ű§ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ Ű§Ùˆ Ù…Ù‚Ű§ÛŒŰłÙ‡ Ú©Ù†ÛŒŰŻ. Ű§Ùˆ همچنین می‌ŰȘÙˆŰ§Ù†ŰŻ Ú©ŰŻ ŰŽÙ…Ű§ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ ŰźÙˆŰŻ Ű§ŰłÚ©Ù† Ú©Ù†ŰŻ.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ŰšÛŒŰŽŰȘ۱ ŰšŰŻŰ§Ù†ÛŒŰŻ", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "ŰšŰ±Ű§ÛŒ ŰšŰ±Ű±ŰłÛŒ Ű±Ù…ŰČÚŻŰ°Ű§Ű±ÛŒ ۳۱ŰȘŰ§ŰłŰ±ÛŒ ۚۧ {name}ی کۧ۱ŰȘ Ű±Ù†ÚŻÛŒ ŰšŰ§Ù„Ű§ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ Ű§Ùˆ ŰȘŰ·ŰšÛŒÙ‚ ŰŻÙ‡ÛŒŰŻ و ۧŰčۯۧۯ ۱ۧ Ù…Ù‚Ű§ÛŒŰłÙ‡ Ú©Ù†ÛŒŰŻ. ۧگ۱ Ù…Ű·Ű§ŰšÙ‚ŰȘ Ù†ŰŻŰ§Ű±Ù†ŰŻŰŒ ŰŹÙŰȘ ŰŻÛŒÚŻŰ±ÛŒ ۧŰČ ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ…Ù†ÛŒ ۱ۧ Ű§Ù…ŰȘŰ­Ű§Ù† Ú©Ù†ÛŒŰŻ. ÙÙ‚Ű· Ú©Ű§ÙÛŒ ۧ۳ŰȘ یک ŰŹÙŰȘ ŰŽÙ…Ű§Ű±Ù‡ Ù…Ű·Ű§ŰšÙ‚ŰȘ ۯۧێŰȘه ŰšŰ§ŰŽÙ†ŰŻ.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "ŰšŰ±Ű§ÛŒ ŰšŰ±Ű±ŰłÛŒ Ű±Ù…ŰČÚŻŰ°Ű§Ű±ÛŒ ۳۱ŰȘŰ§ŰłŰ±ÛŒ ۚۧ {name}ی ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ ŰšŰ§Ù„Ű§ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ Ű§Ùˆ Ù…Ù‚Ű§ÛŒŰłÙ‡ Ú©Ù†ÛŒŰŻ. Ű§Ùˆ همچنین می‌ŰȘÙˆŰ§Ù†ŰŻ Ú©ŰŻ ŰŽÙ…Ű§ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ ŰźÙˆŰŻ Ű§ŰłÚ©Ù† Ú©Ù†ŰŻ.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ŰȘŰșÛŒÛŒŰ±Ű§ŰȘ ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ…Ù†ÛŒ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ŰšŰ±Ű§ÛŒ فŰčŰ§Ù„ Ú©Ű±ŰŻÙ† Ù‚Ű§ŰšÙ„ÛŒŰȘâ€ŒÙ‡Ű§ÛŒ Ű­Ű±ÛŒÙ… ŰŽŰźŰ”ÛŒ ŰąŰȘی ۯ۱ ŰłÛŒÚŻÙ†Ű§Ù„ŰŒ ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ…Ù†ÛŒ ۯ۱ Ű­Ű§Ù„ ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ ۯ۱ Ű·ÙˆÙ„ یک ŰŻÙˆŰ±Ű§Ù† گ۰ۧ۱ Ù‡ŰłŰȘÙ†ŰŻ.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ŰšŰ±Ű§ÛŒ ŰȘŰŁÛŒÛŒŰŻ ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ…Ù†ÛŒŰŒ کۧ۱ŰȘ Ű±Ù†ÚŻÛŒ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ Ù…ŰźŰ§Ű·Űš ŰźÙˆŰŻ Ù…Ű·Ű§ŰšÙ‚ŰȘ ŰŻÙ‡ÛŒŰŻ. ۧگ۱ Ù…Ű·Ű§ŰšÙ‚ŰȘ Ù†ŰŻŰ§Ű±Ù†ŰŻŰŒ ŰŹÙŰȘ ŰŻÛŒÚŻŰ±ÛŒ ۧŰČ ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ…Ù†ÛŒ ۱ۧ Ű§Ù…ŰȘŰ­Ű§Ù† Ú©Ù†ÛŒŰŻ. ÙÙ‚Ű· Ú©Ű§ÙÛŒ ۧ۳ŰȘ یک ŰŹÙŰȘ ŰŽÙ…Ű§Ű±Ù‡ Ù…Ű·Ű§ŰšÙ‚ŰȘ ۯۧێŰȘه ŰšŰ§ŰŽÙ†ŰŻ.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ŰšÙ‡ Ű±Ű§Ù‡Ù†Ù…Ű§ÛŒÛŒ Ù†ÛŒŰ§ŰČ ŰŻŰ§Ű±ÛŒŰŻŰŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ÙÙ‡Ù…ÛŒŰŻÙ…", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ŰšŰčŰŻ ۧŰČ Ű§ÛŒÙ†Ú©Ù‡ ۚۧ Ű§ÛŒÙ† ÙŰ±ŰŻ ÙŸÛŒŰ§Ù…ÛŒ ۱ۯ و ŰšŰŻÙ„ Ú©Ù†ÛŒŰŻŰŒ یک ŰŽÙ…Ű§Ű±Ù‡ Ű§ÛŒÙ…Ù†ÛŒ ŰšŰ±Ű§ÛŒ Ű§Ùˆ Ű§ÛŒŰŹŰ§ŰŻ ŰźÙˆŰ§Ù‡ŰŻ ŰŽŰŻ.", @@ -1267,10 +1359,6 @@ "messageformat": "Ù…ŰŽŰ§Ù‡ŰŻÙ‡Ù” Ű±ŰłŰ§Ù†Ù‡â€ŒÙ‡Ű§ÛŒ Ű§ŰźÛŒŰ±", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "ŰšŰ±Ű§ÛŒ ŰšŰ±Ű±ŰłÛŒ Ű§Ù…Ù†ÛŒŰȘ Ű±Ù…ŰČÚŻŰ°Ű§Ű±ÛŒ ۳۱ŰȘŰ§ŰłŰ±ÛŒ ۚۧ {name}ی ŰŽÙ…Ű§Ű±Ù‡â€ŒÙ‡Ű§ÛŒ ŰšŰ§Ù„Ű§ ۱ۧ ۚۧ ŰŻŰłŰȘÚŻŰ§Ù‡ Ű§Ùˆ Ù…Ù‚Ű§ÛŒŰłÙ‡ Ú©Ù†ÛŒŰŻ. Ű§Ùˆ همچنین می‌ŰȘÙˆŰ§Ù†ŰŻ Ú©ŰŻ QR ŰšŰ§Ù„Ű§ ۱ۧ Ű§ŰłÚ©Ù† Ú©Ù†ŰŻ.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ŰŽÙ…Ű§ هنوŰČ Ù‡ÛŒÚ† ÙŸÛŒŰ§Ù…ÛŒ ۚۧ Ű§ÛŒÙ† Ù…ŰźŰ§Ű·Űš ŰȘŰšŰ§ŰŻÙ„ Ù†Ú©Ű±ŰŻÙ‡â€ŒŰ§ÛŒŰŻ. ŰŽÙ…Ű§Ű±Ù‡â€ŒÛŒ Ű§Ù…Ù†ÛŒŰȘی ÙŸŰł ۧŰČ Ű§Ű±ŰłŰ§Ù„ و ÛŒŰ§ ŰŻŰ±ÛŒŰ§ÙŰȘ Ű§ÙˆÙ„ÛŒÙ† ÙŸÛŒŰ§Ù… ۯ۱ ŰŻŰłŰȘ۱۳ ŰźÙˆŰ§Ù‡ŰŻ ŰšÙˆŰŻ." }, @@ -1334,17 +1422,17 @@ "messageformat": "Ű§Ű·Ù„Ű§ŰčۧŰȘ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ†", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† ÙŸÛŒŰ§Ù…â€ŒÙ‡Ű§", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ÚŻÙŰȘÚŻÙˆ ÙŸŰ§Ú© ŰŽÙˆŰŻŰŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ÙŸÛŒŰ§Ù…â€ŒÙ‡Ű§ ÙŸŰ§Ú© ŰŽÙˆŰŻŰŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Ű§ÛŒÙ† ÚŻÙŰȘÚŻÙˆ ۧŰČ Ű§ÛŒÙ† ŰŻŰłŰȘÚŻŰ§Ù‡ ÙŸŰ§Ú© ŰźÙˆŰ§Ù‡ŰŻ ŰŽŰŻ.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ÙŸÛŒŰ§Ù…â€ŒÙ‡Ű§ÛŒ Ű§ÛŒÙ† ÚŻÙŰȘÚŻÙˆ ۧŰČ Ű§ÛŒÙ† ŰŻŰłŰȘÚŻŰ§Ù‡ ÙŸŰ§Ú© ŰźÙˆŰ§Ù‡ŰŻ ŰŽŰŻ. ŰšŰčŰŻ ۧŰČ ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† ÙŸÛŒŰ§Ù…â€ŒÙ‡Ű§ Ù‡Ù…Ú†Ù†Ű§Ù† می‌ŰȘÙˆŰ§Ù†ÛŒŰŻ Ű§ÛŒÙ† ÚŻÙŰȘÚŻÙˆ ۱ۧ ŰŹŰłŰȘŰŹÙˆ Ú©Ù†ÛŒŰŻ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ŰȘ۱ک ÚŻŰ±ÙˆÙ‡", @@ -1438,6 +1526,14 @@ "messageformat": "ŰȘŰ§Ű±ÛŒŰźÚ†Ù‡ ÙŸÛŒŰ§Ù… ŰŽÙ…Ű§ ŰšŰ±Ű§ÛŒ Ù‡Ű± ŰŻÙˆ ÚŻÙŰȘÚŻÙˆ Ű§ÛŒÙ†ŰŹŰ§ ۧۯŰșŰ§Ù… ŰŽŰŻÙ‡ ۧ۳ŰȘ.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} مŰȘŰčلق ŰšÙ‡ {conversationTitle} ۧ۳ŰȘ. ŰŽÙ…Ű§ Ù‡Ű± ŰŻÙˆ ŰčŰ¶Ùˆ {sharedGroup} Ù‡ŰłŰȘÛŒŰŻ.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} مŰȘŰčلق ŰšÙ‡ {conversationTitle} ۧ۳ŰȘ", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ŰȘŰ§Ù…ŰšÙ†ÛŒÙ„ ŰȘŰ”ÙˆÛŒŰ± ۧŰČ ÙŸÛŒŰ§Ù… نقل قول ŰŽŰŻÙ‡", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ŰȘÙ…Ű§Űł ŰŻÙˆŰšŰ§Ű±Ù‡", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ŰŽŰ±ÙˆŰč ŰȘÙ…Ű§Űł", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ÙŸÛŒÙˆŰłŰȘن ŰšÙ‡ ŰȘÙ…Ű§Űł", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Ű”ŰŻŰ§ÛŒ Ù…ÛŒÚ©Ű±ÙˆÙÙˆÙ† ŰšÙ‡â€ŒŰŻÙ„ÛŒÙ„ ŰȘŰčۯۧۯ ŰČÛŒŰ§ŰŻ کۧ۱ۚ۱ ۭۧ۶۱ ۯ۱ ŰȘÙ…Ű§Űł Ù‚Ű·Űč ŰŽŰŻ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ۧŰčÙ„Ű§Ù†â€ŒÙ‡Ű§ÛŒ ŰȘÙ…Ű§Űł", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ŰžŰ±ÙÛŒŰȘ ŰȘÙ…Ű§Űł ŰȘکمیل ۧ۳ŰȘ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ŰŻÙˆŰ±ŰšÛŒÙ†", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ÙŸÛŒÙˆŰłŰȘن", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ŰŽŰ±ÙˆŰč", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ŰžŰ±ÙÛŒŰȘ ŰȘÙ…Ű§Űł ŰȘکمیل ۧ۳ŰȘ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ŰŻÙˆŰ±ŰšÛŒÙ† ŰșÛŒŰ±ÙŰčŰ§Ù„ ŰŽŰŻ", @@ -1621,10 +1725,6 @@ "messageformat": "Ű±ÙˆŰŽÙ† Ú©Ű±ŰŻÙ† ŰŻÙˆŰ±ŰšÛŒÙ†", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ŰšÛŒâ€ŒŰ”ŰŻŰ§", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Ù…ÛŒÚ©Ű±ÙˆÙÙˆÙ† ŰșÛŒŰ±ÙŰčŰ§Ù„ ŰŽŰŻ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ۚۧŰČ Ú©Ű±ŰŻÙ† Ű”ŰŻŰ§ÛŒ Ù…ÛŒÚ©Ű±ÙˆÙÙˆÙ†", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ۧێŰȘŰ±Ű§Ú©â€ŒÚŻŰ°Ű§Ű±ÛŒ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Ű§Ű±Ű§ŰŠÙ‡ ŰŻŰ§ŰŻÙ† ŰșÛŒŰ±ÙŰčŰ§Ù„ ŰŽŰŻ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Ű§Ű±Ű§ŰŠÙ‡ ۱ۧ مŰȘوقف Ú©Ù†ÛŒŰŻ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ŰČÙ†ÚŻ ŰČŰŻÙ†", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ÚŻŰ±ÙˆÙ‡ ŰšŰ±Ű§ÛŒ ŰČÙ†ÚŻ ŰźÙˆŰ±ŰŻÙ† همهٔ Ù…ŰŽŰ§Ű±Ú©ŰȘâ€ŒÚ©Ù†Ù†ŰŻÚŻŰ§Ù† ŰźÛŒÙ„ÛŒ ŰšŰČ۱گ ۧ۳ŰȘ.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "فŰčŰ§Ù„ Ú©Ű±ŰŻÙ† ŰČÙ†ÚŻ ŰźÙˆŰ±ŰŻÙ†", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ŰźŰ§Ù…ÙˆŰŽ Ú©Ű±ŰŻÙ† ŰČÙ†ÚŻ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Ű±ÙˆŰŽÙ† Ú©Ű±ŰŻÙ† ŰČÙ†ÚŻ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ÚŻŰČÛŒÙ†Ù‡â€ŒÙ‡Ű§ÛŒ ŰšÛŒŰŽŰȘ۱", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ŰŽÙ…Ű§", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ŰŻÙˆŰ±ŰšÛŒÙ† ŰŽÙ…Ű§ ŰźŰ§Ù…ÙˆŰŽ ۧ۳ŰȘ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ŰŻÛŒŰŻÙ† ŰŽÙ…Ű§Ű±Ù‡Ù” Ű§ÛŒÙ…Ù†ÛŒ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ÙŸÛŒŰ§Ù…", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ŰŻÛŒŰŻÙ† ŰŽÙ…Ű§Ű±Ù‡Ù” Ű§ÛŒÙ…Ù†ÛŒ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ŰŽÙ…Ű§Ű±Ù‡ ŰȘلفن ŰšÙ‡ ŰŻŰłŰȘ Ù†ÛŒŰ§Ù…ŰŻ. . ۧŰȘŰ”Ű§Ù„ ŰźÙˆŰŻ ۱ۧ ŰšŰ±Ű±ŰłÛŒ Ú©Ù†ÛŒŰŻ و ŰŻÙˆŰšŰ§Ű±Ù‡ Ű§Ù…ŰȘŰ­Ű§Ù† Ú©Ù†ÛŒŰŻ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ÙˆÛŒŰ±Ű§ÛŒŰŽâ€ŒÙ‡Ű§ ÙÙ‚Ű· ŰȘۧ Ûł ۳ۧŰčŰȘ ŰšŰčŰŻ ۧŰČ Ű§Ű±ŰłŰ§Ù„ Ű§ÛŒÙ† ÙŸÛŒŰ§Ù… Ù‚Ű§ŰšÙ„ ۧŰčÙ…Ű§Ù„ Ù‡ŰłŰȘÙ†ŰŻ.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ÙˆÛŒŰ±Ű§ÛŒŰŽâ€ŒÙ‡Ű§ ÙÙ‚Ű· ŰȘۧ ÛČÛŽ ۳ۧŰčŰȘ ŰšŰčŰŻ ۧŰČ Ű§Ű±ŰłŰ§Ù„ Ű§ÛŒÙ† ÙŸÛŒŰ§Ù… Ù‚Ű§ŰšÙ„ ۧŰčÙ…Ű§Ù„ Ù‡ŰłŰȘÙ†ŰŻ.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ű§ÛŒÙ† ÙŸÛŒŰ§Ù… ÙŸŰ§Ú© ŰŽŰŻ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ÙŰ§ÛŒÙ„ ÙŸÛŒÙˆŰłŰȘ ŰšŰ±Ű§ÛŒ Ù†Ù…Ű§ÛŒŰŽ ŰźÛŒÙ„ÛŒ ŰšŰČ۱گ ۧ۳ŰȘ.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ŰšŰ±ŰźÛŒ ÙŰ§ÛŒÙ„â€ŒÙ‡Ű§ÛŒ ÙŸÛŒÙˆŰłŰȘ ŰšŰ±Ű§ÛŒ Ù†Ù…Ű§ÛŒŰŽ ŰźÛŒÙ„ÛŒ ŰšŰČ۱گ Ù‡ŰłŰȘÙ†ŰŻ.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ŰŻŰ±ÛŒŰ§ÙŰȘ ŰŹŰČŰŠÛŒŰ§ŰȘ کمک Ù…Ű§Ù„ÛŒ Ű§Ù…Ú©Ű§Ù†â€ŒÙŸŰ°ÛŒŰ± Ù†ÛŒŰłŰȘ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ÙÙ‚Ű· ŰłÛŒÚŻÙ†Ű§Ù„ ŰšŰȘۧ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ÙˆÛŒŰ±Ű§ÛŒŰŽ ÙŸÛŒŰ§Ù…â€ŒÙ‡Ű§ ÙÙ‚Ű· ŰšŰ±Ű§ÛŒ Ú©Ű§Ű±ŰšŰ±Ű§Ù† ŰłÛŒÚŻÙ†Ű§Ù„ ŰšŰȘۧ ممکن ۧ۳ŰȘ. ۧگ۱ ÙŸÛŒŰ§Ù…ÛŒ ۱ۧ ÙˆÛŒŰ±Ű§ÛŒŰŽ Ú©Ù†ÛŒŰŻŰŒ ÙÙ‚Ű· ŰšŰ±Ű§ÛŒ Ű§ÙŰ±Ű§ŰŻÛŒ که ۧŰČ ŰȘۧŰČه‌ŰȘŰ±ÛŒÙ† Ù†ŰłŰźÙ‡ ŰłÛŒÚŻÙ†Ű§Ù„ ŰšŰȘۧ ۧ۳ŰȘÙŰ§ŰŻÙ‡ Ù…ÛŒâ€ŒÚ©Ù†Ù†ŰŻ Ù‚Ű§ŰšÙ„ Ù…ŰŽŰ§Ù‡ŰŻÙ‡ ŰźÙˆŰ§Ù‡ŰŻ ŰšÙˆŰŻ.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ÙˆÛŒŰ±Ű§ÛŒŰŽ ÙŸÛŒŰ§Ù…", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ۧگ۱ ÙŸÛŒŰ§Ù…ÛŒ ۱ۧ ÙˆÛŒŰ±Ű§ÛŒŰŽ Ú©Ù†ÛŒŰŻŰŒ ÙÙ‚Ű· ŰšŰ±Ű§ÛŒ Ű§ÙŰ±Ű§ŰŻÛŒ که ۧŰČ ŰȘۧŰČه‌ŰȘŰ±ÛŒÙ† Ù†ŰłŰźÙ‡ ŰłÛŒÚŻÙ†Ű§Ù„ ۧ۳ŰȘÙŰ§ŰŻÙ‡ Ù…ÛŒâ€ŒÚ©Ù†Ù†ŰŻ Ù‚Ű§ŰšÙ„ Ù…ŰŽŰ§Ù‡ŰŻÙ‡ ŰźÙˆŰ§Ù‡ŰŻ ŰšÙˆŰŻ. ŰąÙ†â€ŒÙ‡Ű§ می‌ŰȘÙˆŰ§Ù†Ù†ŰŻ ŰšŰšÛŒÙ†Ù†ŰŻ که ÙŸÛŒŰ§Ù…ÛŒ ۱ۧ ÙˆÛŒŰ±Ű§ÛŒŰŽ Ú©Ű±ŰŻÙ‡â€ŒŰ§ÛŒŰŻ.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ŰȘÙ…Ű§Űł ŰȘŰ”ÙˆÛŒŰ±ÛŒ ŰŻŰ±ÛŒŰ§ÙŰȘی...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ŰźŰ±ÙˆŰŹÛŒ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ŰȘÙ…Ű§Űł ŰȘŰ”ÙˆÛŒŰ±ÛŒ ŰźŰ±ÙˆŰŹÛŒ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ۯ۱ Ű­Ű§Ù„ ŰȘÙ…Ű§Űł ۚۧ ŰŽÙ…Ű§ŰłŰȘ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ۯ۱ Ű­Ű§Ù„ ۧŰȘŰ”Ű§Ù„ ŰŻÙˆŰšŰ§Ű±Ù‡...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "ŰłÛŒÚŻÙ†Ű§Ù„ {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} Ù†ÙŰ±} other {{count,number} Ù†ÙŰ±}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Ù‚Ű·Űč", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ŰȘ۱ک", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Ù…ÛŒÚ©Ű±ÙˆÙÙˆÙ† ŰźŰ§Ù…ÙˆŰŽ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Ù…ÛŒÚ©Ű±ÙˆÙÙˆÙ† Ű±ÙˆŰŽÙ† ۧ۳ŰȘ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ŰČÙ†ÚŻ Ű±ÙˆŰŽÙ† ۧ۳ŰȘ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ŰČÙ†ÚŻ ŰźŰ§Ù…ÙˆŰŽ ۧ۳ŰȘ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ŰȘÙ†ŰžÛŒÙ…Ű§ŰȘ", @@ -3468,13 +3668,25 @@ "messageformat": "ŰȘÙ…Ű§Űł ŰȘÙ…Ű§Ù…â€ŒŰ”ÙŰ­Ù‡", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ŰȘŰșÛŒÛŒŰ± ŰšÙ‡ Ù†Ù…Ű§ÛŒ ŰŽŰšÚ©Ù‡", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ŰȘŰșÛŒÛŒŰ± Ù†Ù…Ű§", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ŰȘŰșÛŒÛŒŰ± ŰšÙ‡ Ù†Ù…Ű§ÛŒ ۔ۭۚŰȘâ€ŒÚ©Ù†Ù†ŰŻÙ‡", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Ù†Ù…Ű§ÛŒ Ù…ŰŽŰšÚ©", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Ù†Ù…Ű§ÛŒ Ù†ÙˆŰ§Ű± ŰŹŰ§Ù†ŰšÛŒ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Ù†Ù…Ű§ÛŒ ŰšÙ„Ù†ŰŻÚŻÙˆ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Ù†Ù…Ű§ ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ ŰŽŰŻ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ŰȘ۱ک Ú©Ű±ŰŻÙ† ŰȘÙ…Ű§Űł", @@ -3576,6 +3788,14 @@ "messageformat": "ŰźÙˆŰš", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ÙˆÛŒŰ±Ű§ÛŒŰŽ ÙŸÛŒŰ§Ù… Ű§Ù…Ú©Ű§Ù†â€ŒÙŸŰ°ÛŒŰ± Ù†ÛŒŰłŰȘ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ÙÙ‚Ű· {max,number} ÙˆÛŒŰ±Ű§ÛŒŰŽ Ù‚Ű§ŰšÙ„â€ŒŰ§ŰčÙ…Ű§Ù„ ŰšÙ‡ Ű§ÛŒÙ† ÙŸÛŒŰ§Ù… ۧ۳ŰȘ.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "مŰȘŰ§Ù”ŰłÙÛŒÙ…ŰŒ ŰąÙ† ÙŸÛŒÙˆÙ†ŰŻ sgnl:// ÙŸŰŽŰȘÛŒŰšŰ§Ù†ÛŒ Ù†Ù…ÛŒâ€ŒŰŽÙˆŰŻ", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ŰźŰ·Ű§ÛŒÛŒ ۯ۱ Ù…ÙˆŰ±ŰŻ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰŽÙ…Ű§ ۱۟ ۯۧۯی Ű§ÛŒÙ† Ù†Ű§Ù… ŰŻÛŒÚŻŰ± ŰšÙ‡ ۭ۳ۧۚ ŰŽÙ…Ű§ ŰȘŰčلق Ù†ŰŻŰ§Ű±ŰŻ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Ű§ÛŒŰŹŰ§ŰŻ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "ÙŸÛŒÙˆÙ†ŰŻ ÛŒŰ§ Ú©ŰŻ QR", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰšŰ§ÛŒŰŻ ۚۧŰČÙ†ŰŽŰ§Ù†ÛŒ ŰŽÙˆŰŻ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ÙŸÛŒÙˆÙ†ŰŻ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰšŰ§ÛŒŰŻ ۚۧŰČÙ†ŰŽŰ§Ù†ÛŒ ŰŽÙˆŰŻ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Ù‡Ù…â€ŒŰ±ŰłŰ§Ù†ÛŒ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒâ€ŒŰȘŰ§Ù†", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ۚۧ Ű§ÛŒÙ† Ú©Ű§Ű±ŰŒ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰŽÙ…Ű§ Ű­Ű°Ù Ù…ÛŒâ€ŒŰŽÙˆŰŻ و ŰłŰ§ÛŒŰ± Ú©Ű§Ű±ŰšŰ±Ű§Ù† می‌ŰȘÙˆŰ§Ù†Ù†ŰŻ ŰąÙ† ۱ۧ ŰšŰ±Ű§ÛŒ ŰźÙˆŰŻ ۚ۱گŰČÛŒÙ†Ù†ŰŻ. ŰąÛŒŰ§ Ù…Ű·Ù…ŰŠÙ† Ù‡ŰłŰȘÛŒŰŻŰŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ű§ÛŒÙ† کۧ۱ Ù…ÙˆŰŹŰš Ű­Ű°Ù Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ و ŰșÛŒŰ±ÙŰčŰ§Ù„ ŰŽŰŻÙ† Ú©ŰŻ و ÙŸÛŒÙˆÙ†ŰŻ QR ŰŽÙ…Ű§ Ù…ÛŒâ€ŒŰŽÙˆŰŻ. «{username}» ۯ۱ ŰŻŰłŰȘ۱۳ ŰŻÛŒÚŻŰ±Ű§Ù† Ù‚Ű±Ű§Ű± ŰźÙˆŰ§Ù‡ŰŻ ÚŻŰ±ÙŰȘ و می‌ŰȘÙˆŰ§Ù†Ù†ŰŻ ŰąÙ† ۱ۧ ŰȘ۔ۭۧۚ Ú©Ù†Ù†ŰŻ. Ù…Ű·Ù…ŰŠÙ† Ù‡ŰłŰȘÛŒŰŻŰŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ŰŻÛŒÚŻŰ± نمی‌ŰȘÙˆŰ§Ù†ÛŒŰŻ ۧ۳ŰȘÙˆŰ±ÛŒâ€ŒÙ‡Ű§ ۱ۧ ۧێŰȘŰ±Ű§Ú©â€ŒÚŻŰ°Ű§Ű±ÛŒ ÛŒŰ§ Ù…ŰŽŰ§Ù‡ŰŻÙ‡ Ú©Ù†ÛŒŰŻ. ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒâ€ŒÙ‡Ű§ÛŒ ۧ۳ŰȘÙˆŰ±ÛŒâ€ŒÙ‡Ű§ÛŒÛŒ که Ű§ŰźÛŒŰ±Ű§Ù‹ ۧێŰȘŰ±Ű§Ú©â€ŒÚŻŰ°Ű§Ű±ÛŒ Ú©Ű±ŰŻÙ‡â€ŒŰ§ÛŒŰŻ نیŰČ ÙŸŰ§Ú© ŰźÙˆŰ§Ù‡Ù†ŰŻ ŰŽŰŻ.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ŰČŰšŰ§Ù†", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ŰČŰšŰ§Ù†", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ŰČŰšŰ§Ù† ŰłÛŒŰłŰȘم", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ŰŹŰłŰȘŰŹÙˆÛŒ ŰČŰšŰ§Ù†â€ŒÙ‡Ű§", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "نŰȘÛŒŰŹÙ‡â€ŒŰ§ÛŒ ŰšŰ±Ű§ÛŒ «{searchTerm}» ÙŸÛŒŰŻŰ§ Ù†ŰŽŰŻ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ŰȘÙ†ŰžÛŒÙ…", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ŰšŰ±Ű§ÛŒ ۧŰčÙ…Ű§Ù„ Ú©Ű±ŰŻÙ†ŰŒ ŰłÛŒÚŻÙ†Ű§Ù„ ۱ۧ ۚۧŰČŰ±Ű§Ù‡â€ŒŰ§Ù†ŰŻŰ§ŰČی Ú©Ù†ÛŒŰŻ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ŰšŰ±Ű§ÛŒ ŰȘŰșÛŒÛŒŰ± ŰČŰšŰ§Ù†ŰŒ ŰšŰ±Ù†Ű§Ù…Ù‡ ŰšŰ§ÛŒŰŻ ۚۧŰČŰ±Ű§Ù‡â€ŒŰ§Ù†ŰŻŰ§ŰČی ŰŽÙˆŰŻ.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ۚۧŰČŰ±Ű§Ù‡â€ŒŰ§Ù†ŰŻŰ§ŰČی", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ ŰšÙ‡ Ù†ŰłŰźÙ‡Ù” {version} Ù…ÙˆŰŹÙˆŰŻ ۧ۳ŰȘ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ŰźŰ·Ű§ÛŒÛŒ ۯ۱ ŰČÙ…Ű§Ù† Ű°ŰźÛŒŰ±Ù‡â€ŒŰłŰ§ŰČی ŰȘÙ†ŰžÛŒÙ…Ű§ŰȘ ŰŽÙ…Ű§ ۱۟ ۯۧۯ. Ù„Ű·ÙŰ§Ù‹ Ù…ŰŹŰŻŰŻŰ§ ŰȘÙ„Ű§ŰŽ Ú©Ù†ÛŒŰŻ", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ÙŸÛŒŰ§Ù…", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ŰłŰšÚ©â€ŒÙ‡Ű§ÛŒ ŰšÛŒŰŽŰȘ۱", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ۚۧŰČÙ†ŰŽŰ§Ù†ÛŒ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ŰȘÙ…Ű§Ù…", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Ű±Ù†ÚŻ ÙŸÛŒÙˆÙ†ŰŻ Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒŰŒ {index,number} ۧŰČ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ۧگ۱ Ú©ŰŻ QR ŰźÙˆŰŻ ۱ۧ ۚۧŰČÙ†ŰŽŰ§Ù†ÛŒ Ú©Ù†ÛŒŰŻŰŒ Ú©ŰŻ و ÙŸÛŒÙˆÙ†ŰŻ QR فŰčلی ŰŻÛŒÚŻŰ± کۧ۱ Ù†ŰźÙˆŰ§Ù‡ŰŻ ک۱ۯ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ۯ۱ Ű­Ű§Ù„ ۚۧŰČÙ†ŰŽŰ§Ù†ÛŒ ÙŸÛŒÙˆÙ†ŰŻ...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "ÙŸÛŒÙˆÙ†ŰŻ و Ú©ŰŻ QR ŰȘÙ†ŰžÛŒÙ… Ù†ŰŽŰŻÙ‡ ۧ۳ŰȘ. ۧŰȘŰ”Ű§Ù„ ŰŽŰšÚ©Ù‡ ŰźÙˆŰŻ ۱ۧ ŰšŰ±Ű±ŰłÛŒ Ú©Ù†ÛŒŰŻ و ŰŻÙˆŰšŰ§Ű±Ù‡ Ű§Ù…ŰȘŰ­Ű§Ù† Ú©Ù†ÛŒŰŻ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ŰȘÙ†ŰžÛŒÙ… Ù†Ű§Ù… Ú©Ű§Ű±ŰšŰ±ÛŒ ŰłÛŒÚŻÙ†Ű§Ù„â€ŒŰȘŰ§Ù†", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "Ű§Ű±ŰłŰ§Ù„ Ù…ŰŹŰŻŰŻ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Ű§Ù‚ŰŻŰ§Ù…Ű§ŰȘ ŰšÛŒŰŽŰȘ۱", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ŰȘÙ…Ű§Űłâ€ŒÙ‡Ű§", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ŰȘÙ…Ű§Űł ŰŹŰŻÛŒŰŻ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ŰȘÙ…Ű§Űł ŰŹŰŻÛŒŰŻ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Ű§Ù‚ŰŻŰ§Ù…Ű§ŰȘ ŰšÛŒŰŽŰȘ۱", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ† ŰȘŰ§Ű±ÛŒŰźÚ†Ù‡ ŰȘÙ…Ű§Űł", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ŰȘŰ§Ű±ÛŒŰźÚ†Ù‡ ŰȘÙ…Ű§Űł ÙŸŰ§Ú© ŰŽÙˆŰŻŰŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Ű§ÛŒÙ† کۧ۱ همه ŰȘŰ§Ű±ÛŒŰźÚ†Ù‡ ŰȘÙ…Ű§Űł ۱ۧ ŰšÙ‡â€ŒŰ·ÙˆŰ± ŰŻŰ§ŰŠÙ…ÛŒ ÙŸŰ§Ú© ŰźÙˆŰ§Ù‡ŰŻ ک۱ۯ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ÙŸŰ§Ú© Ú©Ű±ŰŻÙ†", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "ŰłÙˆŰ§ŰšÙ‚ ŰȘÙ…Ű§Űłâ€ŒÙ‡Ű§ ÙŸŰ§Ú© ŰŽŰŻ.", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ŰšŰ±Ű§ÛŒ Ù…ŰŽŰ§Ù‡ŰŻÙ‡ ÛŒŰ§ ŰŽŰ±ÙˆŰč ŰȘÙ…Ű§Űł کلیک Ú©Ù†ÛŒŰŻ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ŰŹŰłŰȘŰŹÙˆ", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "فیلŰȘ۱ Ú©Ű±ŰŻÙ† ۚ۱ ۧ۳ۧ۳ «ۧŰČ ŰŻŰłŰȘ Ű±ÙŰȘه»", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ŰȘŰčÙˆÛŒŰ¶", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ŰšŰŻÙˆÙ† ŰȘÙ…Ű§Űł Ù‡Ű§ÛŒ ŰŹŰŻÛŒŰŻ. ۚۧ ŰȘÙ…Ű§Űł ۚۧ یک ŰŻÙˆŰłŰȘ ŰŽŰ±ÙˆŰč Ú©Ù†ÛŒŰŻ.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "نŰȘÛŒŰŹÙ‡â€ŒŰ§ÛŒ ŰšŰ±Ű§ÛŒ «{query}» ÙŸÛŒŰŻŰ§ Ù†ŰŽŰŻ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ÙˆŰ±ÙˆŰŻÛŒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ŰźŰ±ÙˆŰŹÛŒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ۧŰČŰŻŰłŰȘâ€ŒŰ±ÙŰȘه", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ù…Ú©Ű§Ù„Ù…Ù‡ Ű§ŰźÛŒŰ±ÛŒ ÙˆŰŹÙˆŰŻ Ù†ŰŻŰ§Ű±ŰŻ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "نŰȘÛŒŰŹÙ‡â€ŒŰ§ÛŒ ŰšŰ±Ű§ÛŒ «{query}» ÙŸÛŒŰŻŰ§ Ù†ŰŽŰŻ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ŰźŰ±ÙˆŰŹÛŒ} other {ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ŰŻŰ±ÛŒŰ§ÙŰȘی}}} Video {{direction, select, Outgoing {ŰȘÙ…Ű§Űł ŰȘŰ”ÙˆÛŒŰ±ÛŒ ŰźŰ±ÙˆŰŹÛŒ} other {ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ŰŻŰ±ÛŒŰ§ÙŰȘی}}} Group {{direction, select, Outgoing {ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ ŰźŰ±ÙˆŰŹÛŒ} other {ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ ÙˆŰ±ÙˆŰŻÛŒ}}} other {{direction, select, Outgoing {ŰȘÙ…Ű§Űł ŰźŰ±ÙˆŰŹÛŒ} other {ŰȘÙ…Ű§Űł ÙˆŰ±ÙˆŰŻÛŒ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ۧŰČŰŻŰłŰȘâ€ŒŰ±ÙŰȘه} Video {ŰȘÙ…Ű§Űł ŰȘŰ”ÙˆÛŒŰ±ÛŒ ۧŰČ ŰŻŰłŰȘ Ű±ÙŰȘه} Group {ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ ۧŰČŰŻŰłŰȘâ€ŒŰ±ÙŰȘه} other {ŰȘÙ…Ű§Űł ŰšÛŒâ€ŒÙŸŰ§ŰłŰź}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ŰšÛŒâ€ŒÙŸŰ§ŰłŰź} Video {ŰȘÙ…Ű§Űł ŰȘŰ”ÙˆÛŒŰ±ÛŒ ŰšÛŒâ€ŒÙŸŰ§ŰłŰź} Group {ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ ŰšÛŒâ€ŒÙŸŰ§ŰłŰź} other {ŰȘÙ…Ű§Űł ŰšÛŒâ€ŒÙŸŰ§ŰłŰź}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ŰȘÙ…Ű§Űł Ű”ÙˆŰȘی ۱ۯ ŰŽŰŻÙ‡} Video {ŰȘÙ…Ű§Űł ŰȘŰ”ÙˆÛŒŰ±ÛŒ ۱ۯ ŰŽŰŻÙ‡} Group {ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ ۱ۯ ŰŽŰŻÙ‡} other {ŰȘÙ…Ű§Űł ۱ۯ ŰŽŰŻÙ‡}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} Ù†ÙŰ± ŰŻÛŒÚŻŰ± ۯ۱ Ű­Ű§Ù„ ŰȘŰ§ÛŒÙŸ ۧ۳ŰȘ.} other {{count,number} Ù†ÙŰ± ŰŻÛŒÚŻŰ± ۯ۱ Ű­Ű§Ù„ ŰȘŰ§ÛŒÙŸ Ù‡ŰłŰȘÙ†ŰŻ.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ŰȘۧŰČÙ‡â€ŒÙ‡Ű§", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ŰȘŰșÛŒÛŒŰ±Ű§ŰȘ Ú©ÙˆÚ†Ú©ŰŒ Ű±ÙŰč Ű§ŰŽÚ©Ű§Ù„Ű§ŰȘ و ŰšÙ‡ŰšÙˆŰŻ ŰčÙ…Ù„Ú©Ű±ŰŻ. ۚۧۚŰȘ ۧ۳ŰȘÙŰ§ŰŻÙ‡ ۧŰČ ŰłÛŒÚŻÙ†Ű§Ù„ ŰłÙŸŰ§ŰłÚŻŰČŰ§Ű±ÛŒÙ…!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ۯ۱ Ű§ÛŒÙ† ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ Ú†Ù†ŰŻ Ù…ÙˆŰ±ŰŻ Ù…Ű±ŰšÙˆŰ· ŰšÙ‡ ŰȘÙ…Ű§Űłâ€ŒÙ‡Ű§ÛŒ Ű”ÙˆŰȘی و ÙˆÛŒŰŻŰŠÙˆÛŒÛŒ ŰšÙ‡ŰšÙˆŰŻ ÛŒŰ§ÙŰȘه ۧ۳ŰȘ و همچنین Ú†Ù†ŰŻ ŰšÙ‡â€ŒŰ±ÙˆŰČŰ±ŰłŰ§Ù†ÛŒ ŰŹŰČŰŠÛŒ ۯ۱ Ű§ŰłÙ†Ű§ŰŻ Ű”ÙˆŰ±ŰȘ ÚŻŰ±ÙŰȘه ۧ۳ŰȘ (ۚۧ ŰȘێک۱ ۧŰČ {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Ű­Ű§Ù„Ű§ می‌ŰȘÙˆŰ§Ù†ÛŒŰŻ ŰšŰŻÙˆÙ† ŰȘŰșÛŒÛŒŰ± ŰȘÙ†ŰžÛŒÙ…Ű§ŰȘ ŰłÛŒŰłŰȘم ŰźÙˆŰŻŰŒ ŰČŰšŰ§Ù† Ű§Ù†ŰȘŰźŰ§ŰšÛŒâ€ŒŰȘŰ§Ù† ۯ۱ ŰłÛŒÚŻÙ†Ű§Ù„ ۱ۧ ŰȘŰșÛŒÛŒŰ± ŰŻÙ‡ÛŒŰŻ (ŰȘÙ†ŰžÛŒÙ…Ű§ŰȘ ŰłÛŒÚŻÙ†Ű§Ù„ > Ù†Ù…Ű§ÛŒ ŰžŰ§Ù‡Ű±ÛŒ > ŰČŰšŰ§Ù†)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ŰšŰčŰ¶ÛŒ Ù†Ù…Ű§ŰŻÙ‡Ű§ÛŒ ۧŰčÙ„Ű§Ù† ÚŻŰ±ÙˆÙ‡ÛŒ ۱ۧ ŰšÙ‡â€ŒŰ±ÙˆŰČ Ú©Ű±ŰŻÛŒÙ…." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ŰȘŰŁŰźÛŒŰ± کوŰȘŰ§Ù‡ÛŒ ۱ۧ که ÚŻŰ§Ù‡ÛŒ ŰšŰčŰŻ ۧŰČ ÙŸÛŒÙˆŰłŰȘن ŰšÙ‡ ŰŹÙ„ŰłÛ€ ŰȘÙ…Ű§Űł ۯ۱ macOS ۱۟ Ù…ÛŒâ€ŒŰŻŰ§ŰŻ ŰšŰ±Ű·Ű±Ù Ú©Ű±ŰŻÛŒÙ…." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Ű§Ù†ÛŒÙ…ÛŒŰŽÙ† گ۰ۧ۱ ۱ۧ ŰšŰ±Ű§ÛŒ ŰčÙ†ÙˆŰ§Ù† ÙˆÛŒŰŻŰŠÙˆÙ‡Ű§ŰŒ ۯ۱ ŰČÙ…Ű§Ù†ÛŒ که Ú©ŰłÛŒ ŰšÙ‡ ŰȘÙ…Ű§Űł ÚŻŰ±ÙˆÙ‡ÛŒ Ù…ÛŒâ€ŒÙŸÛŒÙˆÙ†ŰŻŰŻ ÛŒŰ§ ۧŰČ ŰąÙ† ۟ۧ۱ۏ Ù…ÛŒâ€ŒŰŽÙˆŰŻŰŒ Ű±ÙŰč Ű§ŰŽÚ©Ű§Ù„ Ú©Ű±ŰŻÙ‡â€ŒŰ§ÛŒÙ…." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Ű­Ű§Ù„Ű§ می‌ŰȘÙˆŰ§Ù†ÛŒŰŻ Ű±ÙˆÛŒ یک ŰčÚ©Űł Ù†Ù…Ű§ÛŒÙ‡ ÛŒŰ§ ŰąÙˆŰ§ŰȘۧ۱ ÚŻŰ±ÙˆÙ‡ÛŒ ۯ۱ ۳۱ۚ۱گ ÚŻÙŰȘÚŻÙˆ کلیک Ú©Ù†ÛŒŰŻ ŰȘۧ ŰšÙ‡ ۳۱ŰčŰȘ ŰšÙ‡ ŰȘÙ†ŰžÛŒÙ…Ű§ŰȘ ÚŻÙŰȘÚŻÙˆ ŰŻŰłŰȘŰ±ŰłÛŒ ÙŸÛŒŰŻŰ§ Ú©Ù†ÛŒŰŻ ÛŒŰ§ ۧ۳ŰȘÙˆŰ±ÛŒâ€ŒÙ‡Ű§ÛŒ ŰŻÛŒŰŻÙ‡ Ù†ŰŽŰŻÙ‡ ۧŰČ ŰąÙ† ÚŻÙŰȘÚŻÙˆ ۱ۧ Ù…ŰŽŰ§Ù‡ŰŻÙ‡ Ú©Ù†ÛŒŰŻ. ŰłÙŸŰ§ŰłŰŒ {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/fi/messages.json b/_locales/fi/messages.json index 5854103f6c..c3d40b2522 100644 --- a/_locales/fi/messages.json +++ b/_locales/fi/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Tietokantavirhe", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Tapahtui tietokantavirhe. Voit kopioida virheen tiedot ja ottaa yhteyttĂ€ Signal-tukeen ongelman korjaamiseksi. Jos sinun on kĂ€ytettĂ€vĂ€ Signalia heti, voit poistaa Signalin tiedot ja kĂ€ynnistÀÀ ohjelman uudelleen.\n\nOta yhteyttĂ€ tukeen osoitteessa: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Tuhoa kaikki tiedot ja kĂ€ynnistĂ€ uudelleen", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Tuhoa tiedot ja kĂ€ynnistĂ€ uudelleen", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Poistetaanko kaikki tiedot pysyvĂ€sti?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Kaikki viestihistoriasi ja mediasi poistetaan tĂ€ltĂ€ laitteelta pysyvĂ€sti. Voit kĂ€yttÀÀ Signalia tĂ€llĂ€ laitteella, kun olet yhdistĂ€nyt sen tiliisi uudelleen. TĂ€mĂ€ ei poista mitÀÀn tietoja puhelimestasi.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Tietokantasi versio ei vastaa tĂ€tĂ€ Signal-versiota. Varmista, ettĂ€ avaat Signalin uusimman version tietokoneellasi.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Tiedosto", @@ -300,6 +316,70 @@ "messageformat": "Keskustelut", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Jokin meni vikaan kĂ€yttĂ€jĂ€nimessĂ€. Se ei ole enÀÀ liitetty tiliisi. Voit yrittÀÀ asettaa sen uudelleen tai valita uuden kĂ€yttĂ€jĂ€nimen.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Korjaa nyt", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Jokin meni vikaan kĂ€yttĂ€jĂ€nimesi QR-koodissa ja linkissĂ€. Linkki ei ole enÀÀ kelvollinen. Luo uusi linkki, jonka voit jakaa muille.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Korjaa nyt", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "NĂ€ytĂ€ vĂ€lilehdet", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Piilota vĂ€lilehdet", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Tapahtui virhe", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} lukematonta", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Merkitty lukemattomaksi", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Keskustelut", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Puhelut", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Tarinat", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Asetukset", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "PĂ€ivitĂ€ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profiili", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Takaisin", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Arkistoidut keskustelut palautetaan postilaatikkoon, jos niihin tulee uusia viestejĂ€.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Soita silti", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Liity silti", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Jatka puhelua", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Turvanumeroita pĂ€ivitetÀÀn.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Lue lisÀÀ", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Edellinen turvanumero", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Seuraava turvanumero", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Turvanumeroversio, {index,number}/{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Merkitse vahvistetuksi", @@ -663,33 +747,41 @@ "messageformat": "Poista varmennus", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Varmenna pÀÀstĂ€ pÀÀhĂ€n -salaus henkilön {name} kanssa vertaamalla yllĂ€ olevia numeroita hĂ€nen laitteeseensa. Henkilö voi myös skannata koodisi laitteellaan.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Lue lisÀÀ", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Varmenna pÀÀstĂ€ pÀÀhĂ€n -salaus henkilön {name} kanssa vertaamalla, ettĂ€ numero yllĂ€ olevassa vĂ€rikortissa vastaa hĂ€nen laitettaan. Jos numerot eivĂ€t vastaa, kokeile toista turvanumeroparia. Vain yhden parin on vastattava.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Varmenna pÀÀstĂ€ pÀÀhĂ€n -salaus henkilön {name} kanssa vertaamalla yllĂ€ olevia numeroita hĂ€nen laitteeseensa. Henkilö voi myös skannata koodisi laitteellaan.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Muutoksia turvanumeroihin", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Turvanumeroita pĂ€ivitetÀÀn siirtymĂ€kauden aikana, jotta Signalin tulevat yksityisyysominaisuudet voidaan ottaa kĂ€yttöön.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Tarkista turvanumerot varmistamalla, ettĂ€ vĂ€rikortin numero vastaa yhteystietosi laitetta. Jos numerot eivĂ€t vastaa, kokeile toista turvanumeroparia. Vain yhden parin on vastattava.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Tarvitsetko apua?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "SelvĂ€", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "TĂ€lle henkilölle luodaan turvanumero, kun olet vaihtanut viestejĂ€ hĂ€nen kanssaan.", @@ -1267,10 +1359,6 @@ "messageformat": "NĂ€ytĂ€ Ă€skeinen media", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Varmenna pÀÀstĂ€ pÀÀhĂ€n -salauksen turvallisuus henkilön {name} kanssa vertaamalla yllĂ€ olevia numeroita hĂ€nen laitteeseensa. Henkilö voi myös skannata yllĂ€ olevan QR-koodin.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Et ole lĂ€hettĂ€nyt tai vastaanottanut vielĂ€ viestejĂ€ tĂ€mĂ€n yhteystiedon kanssa. Turvanumero on saatavilla vasta ensimmĂ€isen viestin jĂ€lkeen." }, @@ -1334,17 +1422,17 @@ "messageformat": "Tietoja", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Poista", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Poista viestit", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Poistetaanko keskustelu?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Poistetaanko viesti?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "TĂ€mĂ€ keskustelu poistetaan tĂ€ltĂ€ laitteelta.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "TĂ€mĂ€n keskustelun viestit poistetaan tĂ€stĂ€ laitteesta. Voit edelleen etsiĂ€ tĂ€tĂ€ keskustelua viestien poistamisen jĂ€lkeen.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Poistu ryhmĂ€stĂ€", @@ -1438,6 +1526,14 @@ "messageformat": "Molempien keskusteluiden viestihistoria on yhdistetty tĂ€hĂ€n.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} kuuluu keskusteluun {conversationTitle}. Olette molemmat ryhmĂ€n {sharedGroup} jĂ€seniĂ€.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} kuuluu keskusteluun {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Lainatun kuvaviestin pikkukuva", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Soita uudelleen", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Aloita puhelu", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Liity puheluun", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofonisi on mykistetty, koska puhelussa on paljon osanottajia", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Puheluilmoitukset", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Puhelu on tĂ€ynnĂ€", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Liity", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Aloita", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Puhelu tĂ€ynnĂ€", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera poistettu kĂ€ytöstĂ€", @@ -1621,10 +1725,6 @@ "messageformat": "KĂ€ynnistĂ€ kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "MykistĂ€", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofoni poistettu kĂ€ytöstĂ€", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Poista mikrofonin mykistys", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Jaa", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Esitys estetty", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Lopeta esitys", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Soita", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "RyhmĂ€ on liian suuri soittaaksesi osallistujille.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Salli soittaminen", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Laita soittoÀÀni pois pÀÀltĂ€", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Laita soittoÀÀni pÀÀlle", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "LisÀÀ valintoja", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "SinĂ€", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kamerasi on pois pÀÀltĂ€", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "NĂ€ytĂ€ turvanumero", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Viesti", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "NĂ€ytĂ€ turvanumero", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Puhelinnumeron noutaminen epĂ€onnistui. Tarkista verkkoyhteys ja yritĂ€ uudelleen.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Muokkauksia voidaan tehdĂ€ vain 3 tunnin kuluessa tĂ€mĂ€n viestin lĂ€hettĂ€misestĂ€.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Muokkauksia voidaan tehdĂ€ vain 24 tunnin kuluessa tĂ€mĂ€n viestin lĂ€hettĂ€misestĂ€.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "TĂ€mĂ€ viesti poistettiin.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Liitetiedosto on liian suuri nĂ€ytettĂ€vĂ€ksi.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Jotkin liitetiedostot ovat liian suuria nĂ€ytettĂ€viksi.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Lahjoituksen tietoja ei voitu noutaa", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Vain Signalin beetaversio", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Viestien muokkaus on kĂ€ytettĂ€vissĂ€ vain Signalin beetaversiossa. Jos muokkaat viestiĂ€, se nĂ€kyy vain Signalin uusimman beetaversion kĂ€yttĂ€jille.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Muokkaa viestiĂ€", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Jos muokkaat viestiĂ€, se nĂ€kyy vain Signalin uusimpien versioiden kĂ€yttĂ€jille. He nĂ€kevĂ€t, ettĂ€ muokkasit viestiĂ€.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Saapuva videopuhelu
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "LĂ€htevĂ€ ÀÀnipuhelu", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Soitettu videopuhelu", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} soittaa sinulle", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "YhdistetÀÀn uudelleen
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} henkilöÀ} other {{count,number} henkilöÀ}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ÄÀnipuhelu", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Lopeta", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Poistu", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofoni pois pÀÀltĂ€", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofoni pÀÀllĂ€", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "SoittoÀÀni pÀÀllĂ€", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "SoittoÀÀni pois pÀÀltĂ€", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Asetukset", @@ -3468,13 +3668,25 @@ "messageformat": "Koko nĂ€ytön puhelu", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Vaihda ruutunĂ€kymÀÀn", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Vaihda nĂ€kymÀÀ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Vaihda kaiutinnĂ€kymÀÀn", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "RuudukkonĂ€kymĂ€", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Sivupalkin nĂ€kymĂ€", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Aktiivisen puhujan nĂ€kymĂ€", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "NĂ€kymĂ€ pĂ€ivitetty", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Poistu puhelusta", @@ -3576,6 +3788,14 @@ "messageformat": "SelvĂ€", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ViestiĂ€ ei voi muokata", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "TĂ€hĂ€n viestiin voidaan tehdĂ€ vain {max,number} muokkausta.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Pahoittelut! TĂ€mĂ€ sgnl:// -linkki ei toimi.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "KĂ€yttĂ€jĂ€nimi", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Jokin meni vikaan kĂ€yttĂ€jĂ€nimessĂ€. Se ei ole enÀÀ liitetty tiliisi.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Poista kĂ€yttĂ€jĂ€tunnus", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Luo kĂ€yttĂ€jĂ€tunnus", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-koodi tai linkki", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "KĂ€yttĂ€jĂ€nimi on nollattava", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "KĂ€yttĂ€jĂ€nimen linkki on nollattava", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Jaa kĂ€yttĂ€jĂ€nimesi", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Poista kĂ€yttĂ€jĂ€tunnus", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "TĂ€mĂ€ poistaa kĂ€yttĂ€jĂ€tunnuksesi antaen muiden kĂ€yttĂ€jien ottaa se kĂ€yttöön. Oletko varma?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "TĂ€mĂ€ poistaa kĂ€yttĂ€jĂ€nimesi ja poistaa QR-koodisi ja linkkisi kĂ€ytöstĂ€. Sen jĂ€lkeen kĂ€yttĂ€jĂ€nimi \"{username}\" on muiden kĂ€ytettĂ€vissĂ€. Oletko varma?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Et voi enÀÀ jakaa tai nĂ€hdĂ€ tarinoita. Myös viimeksi jakamasi tarinoiden pĂ€ivitykset poistetaan.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Kieli", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Kieli", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "JĂ€rjestelmĂ€n kieli", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Hae kieliĂ€", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Ei tuloksia haulle \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Aseta", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Ota kĂ€yttöön kĂ€ynnistĂ€mĂ€llĂ€ Signal uudelleen", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Jos haluat vaihtaa kielen, sovellus on kĂ€ynnistettĂ€vĂ€ uudelleen.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "KĂ€ynnistĂ€ uudelleen", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "PĂ€ivitĂ€ saatavilla olevaan versioon {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Asetuksia tallentaessa tapahtui virhe. YritĂ€ uudelleen.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Viesti", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "LisÀÀ tyylejĂ€", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Palauta alkuasetuksiin", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Valmis", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "KĂ€yttĂ€jĂ€nimilinkin vĂ€ri, {index,number}/{total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Jos nollaat QR-koodin, nykyinen QR-koodisi ja linkkisi eivĂ€t enÀÀ toimi.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Nollataan linkkiÀ ", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-koodia ja linkkiĂ€ ei ole asetettu. Tarkista verkkoyhteys ja yritĂ€ uudelleen.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "MÀÀritĂ€ Signal-kĂ€yttĂ€jĂ€nimesi", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "muokattu", + "messageformat": "Muokattu", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "LĂ€hetĂ€ uudelleen", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "LisĂ€toimintoja", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Puhelut", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Uusi puhelu", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Uusi puhelu", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "LisĂ€toimintoja", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "TyhjennĂ€ puheluhistoria", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "TyhjennetÀÀnkö puheluhistoria?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "TĂ€mĂ€ poistaa pysyvĂ€sti koko puheluhistorian", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "TyhjennĂ€", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Puheluhistoria tyhjennetty", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "NĂ€ytĂ€ tai aloita puhelu napsauttamalla", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Hae", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Suodata vastaamattomat puhelut", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Ota kĂ€yttöön", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ei uusia soittoja. Aloita soittamalla kaverillesi.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Ei tuloksia haulle \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Saapuva", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "LĂ€htevĂ€", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Vastaamaton", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "RyhmĂ€puhelu", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ei viimeaikaisia keskusteluja.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Ei tuloksia haulle \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {LĂ€htevĂ€ ÀÀnipuhelu} other {Saapuva ÀÀnipuhelu}}} Video {{direction, select, Outgoing {Soitettu videopuhelu} other {Vastattu videopuhelu}}} Group {{direction, select, Outgoing {LĂ€htevĂ€ ryhmĂ€puhelu} other {Saapuva ryhmĂ€puhelu}}} other {{direction, select, Outgoing {LĂ€htevĂ€ puhelu} other {Saapuva puhelu}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Vastaamaton ÀÀnipuhelu} Video {Vastaamaton videopuhelu} Group {Vastaamaton ryhmĂ€puhelu} other {Vastaamatta jÀÀnyt puhelu}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Vastaamaton ÀÀnipuhelu} Video {Vastaamaton videopuhelu} Group {Vastaamaton ryhmĂ€puhelu} other {Vastaamaton puhelu}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {HylĂ€tty ÀÀnipuhelu} Video {HylĂ€tty videopuhelu} Group {HylĂ€tty ryhmĂ€puhelu} other {HylĂ€tty puhelu}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} kĂ€yttĂ€jĂ€ kirjoittaa.} other {{count,number} kĂ€yttĂ€jÀÀ kirjoittaa.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Uudet ominaisuudet", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "PieniĂ€ sÀÀtöjĂ€, virheenkorjauksia ja suorituskykyparannuksia. Kiitos, ettĂ€ kĂ€ytĂ€t Signalia!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "TĂ€mĂ€ pĂ€ivitys sisĂ€ltÀÀ muutamia ÀÀni- ja videopuheluiden parannuksia sekĂ€ joitakin pieniĂ€ dokumentaatiopĂ€ivityksiĂ€ (kiitos {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Nyt voit vaihtaa valitsemasi kielen Signalissa ilman, ettĂ€ muutat jĂ€rjestelmĂ€asetuksia (Signalin asetukset > Ulkoasu > Kieli)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "PĂ€ivitimme ryhmĂ€ilmoitusten kuvakkeita." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Korjasimme lyhyen viiveen, joka esiintyi joskus puhelun aulaan liittymisen jĂ€lkeen macOS-laitteilla." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Olemme korjanneet videoruutujen siirtymĂ€animaation, kun joku liittyy ryhmĂ€puheluun tai poistuu siitĂ€." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Nyt voit napsauttaa profiilikuvaa tai ryhmĂ€n avataria chatin otsikossa pÀÀstĂ€ksesi nopeasti chatin asetuksiin tai nĂ€hdĂ€ksesi chatissa olevat lukemattomat tarinat. Kiitos {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index 65e68c6299..9228a4d1d2 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Erreur de base de donnĂ©es", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Une erreur liĂ©e Ă  la base de donnĂ©es s’est produite. Vous pouvez transfĂ©rer les dĂ©tails du problĂšme Ă  l’équipe d’assistance Signal pour qu’elle vous aide Ă  le rĂ©soudre. Si vous devez utiliser Signal immĂ©diatement, vous pouvez supprimer vos donnĂ©es et redĂ©marrer. \n\nContactez l’équipe d’assistance en vous rendant sur : {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Supprimer toutes les donnĂ©es et relancer", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Supprimer les donnĂ©es et redĂ©marrer", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Supprimer dĂ©finitivement toutes les donnĂ©es ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Tout l’historique de vos messages et de vos fichiers sera dĂ©finitivement supprimĂ© de cet appareil. Vous pourrez utiliser Signal sur cet appareil aprĂšs l’avoir reliĂ©. Cette action ne supprimera aucune donnĂ©e de votre tĂ©lĂ©phone.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "La version de votre base de donnĂ©es ne peut pas supporter cette version de Signal. Assurez-vous d’ouvrir la derniĂšre version de Signal sur votre ordinateur.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fichier", @@ -300,6 +316,70 @@ "messageformat": "Conversations", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Une erreur s’est produite et votre nom d’utilisateur n’est plus associĂ© Ă  votre compte. Vous pouvez tenter de le reconfigurer ou en choisir un autre.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "RĂ©soudre", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Une erreur s'est produite et vos code QR et lien d'utilisateur ne sont plus valides. CrĂ©ez un nouveau lien Ă  partager avec d’autres utilisateurs.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "RĂ©soudre", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Afficher les onglets", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Masquer les onglets", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Une erreur s’est produite", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} non lu(s)", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "MarquĂ© comme non lu", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Conversations", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Appels", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ParamĂštres", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Mettre Signal Ă  jour", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Retour", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ces conversations sont archivĂ©es et n’apparaĂźtront dans la boĂźte de rĂ©ception que si de nouveaux messages s'y ajoutent.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Appeler quand mĂȘme", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Participer quand mĂȘme", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Poursuivre l’appel", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Les numĂ©ros de sĂ©curitĂ© sont mis Ă  jour.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "En apprendre davantage", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "NumĂ©ro de sĂ©curitĂ© prĂ©cĂ©dent", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "NumĂ©ro de sĂ©curitĂ© suivant", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Version du numĂ©ro de sĂ©curitĂ©, {index,number} de {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marquer comme confirmĂ©", @@ -663,33 +747,41 @@ "messageformat": "Annuler la confirmation", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Pour vĂ©rifier le chiffrement de bout en bout avec {name}, comparez les chiffres ci-dessus avec leur appareil. Ils peuvent Ă©galement lire votre code avec leur appareil.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "En savoir plus", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Pour vĂ©rifier le cryptage de bout en bout avec {name}, faites correspondre la carte de couleur en haut avec leur appareil et comparez-en les chiffres. Si ces numĂ©ros ne correspondent pas, essayez l'autre paire de numĂ©ros de sĂ©curitĂ©. Une seule paire doit ĂȘtre associĂ©e.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Pour vĂ©rifier le chiffrement de bout en bout avec {name}, comparez les chiffres ci-dessus avec leur appareil. Ils peuvent Ă©galement lire votre code avec leur appareil.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Modifications des numĂ©ros de sĂ©curitĂ©", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Les numĂ©ros de sĂ©curitĂ© sont mis Ă  jour au cours d'une pĂ©riode de transition afin d'activer les prochaines fonctions de confidentialitĂ© de Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Pour vĂ©rifier les numĂ©ros de sĂ©curitĂ©, faites correspondre ceux de la carte de couleur avec ceux de l'appareil de votre contact. Si ces numĂ©ros ne correspondent pas, essayez l'autre paire de numĂ©ros de sĂ©curitĂ©. Une seule paire doit ĂȘtre associĂ©e.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Besoin d’aide ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Compris", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Un numĂ©ro de sĂ©curitĂ© sera créé avec cette personne aprĂšs l'Ă©change de messages.", @@ -1267,10 +1359,6 @@ "messageformat": "Afficher les mĂ©dias rĂ©cents", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Pour confirmer la sĂ©curitĂ© de votre chiffrement de bout en bout avec {name}, comparez les chiffres ci-dessus avec ceux de son appareil. Ils peuvent Ă©galement lire votre code QR avec leur appareil.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Vous n’avez pas encore Ă©changĂ© de messages avec ce contact. Votre numĂ©ro de sĂ©curitĂ© sera accessible aprĂšs le premier message." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Supprimer", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Supprimer les messages", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Supprimer la conversation ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Supprimer le message ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Cette conversation sera supprimĂ©e de cet appareil.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Les messages de cette conversation seront supprimĂ©s de cet appareil. Vous pourrez tout de mĂȘme rechercher cette conversation aprĂšs avoir supprimĂ© les messages.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Quitter le groupe", @@ -1438,6 +1526,14 @@ "messageformat": "L’historique de vos messages contenus dans les deux conversations a Ă©tĂ© fusionnĂ© ici.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} appartient Ă  {conversationTitle}. Vous ĂȘtes tous deux membres du groupe {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} appartient Ă  {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Imagette du message citĂ©", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Rappeler", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "DĂ©marrer un appel", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Me joindre Ă  l’appel", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Microphone coupĂ© en raison du nombre de participants Ă  l’appel", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Notifications d’appels", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "L’appel est complet", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "CamĂ©ra", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Rejoindre", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Commencer", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Appel complet", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "La camĂ©ra est dĂ©sactivĂ©e", @@ -1621,10 +1725,6 @@ "messageformat": "Activer la camĂ©ra", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Sourdine", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Le microphone a Ă©tĂ© dĂ©sactivĂ©", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "RĂ©activer le microphone", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Partager", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PrĂ©sentation dĂ©sactivĂ©e", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ArrĂȘter la prĂ©sentation", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Sonnerie", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Le groupe est trop grand pour appeler tous les participants.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Activer la sonnerie", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "DĂ©sactiver la sonnerie", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Activer la sonnerie", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Plus d’options", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Vous", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Votre camĂ©ra est dĂ©sactivĂ©e", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Afficher le numĂ©ro de sĂ©curitĂ©", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Écrire", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Afficher le numĂ©ro de sĂ©curitĂ©", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Échec de la rĂ©cupĂ©ration du numĂ©ro de tĂ©lĂ©phone. VĂ©rifiez votre connexion et rĂ©essayez.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Les modifications peuvent ĂȘtre appliquĂ©es uniquement dans un dĂ©lai de 3 heures Ă  compter de l’envoi du message.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Vous ne pouvez modifier que pendant les 24 heures suivant l’envoi du message.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ce message a Ă©tĂ© supprimĂ©.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "PiĂšce jointe trop volumineuse pour ĂȘtre affichĂ©e.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Certaines piĂšces jointes sont trop volumineuses pour ĂȘtre affichĂ©es.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Impossible de rĂ©cupĂ©rer les dĂ©tails du don", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Pour la version bĂȘta de Signal uniquement", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "La fonction permettant de modifier les messages est disponible pour les utilisateurs de la version bĂȘta de Signal uniquement. Les modifications apportĂ©es Ă  un message ne seront visibles que pour les personnes utilisant la derniĂšre version bĂȘta de Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Modifier le message", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Les modifications apportĂ©es aux messages ne seront visibles que par les personnes utilisant les derniĂšres versions de Signal. Elles pourront voir que vous avez modifiĂ© un message.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Appel vidĂ©o entrant
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Appel vocal sortant", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Appel vidĂ©o sortant", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} vous appelle", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Reconnexion
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} personne} other {{count,number} personnes}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Appel audio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Terminer", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Quitter", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Micro dĂ©sactivĂ©", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Micro activĂ©", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Sonnerie activĂ©e", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Sonnerie dĂ©sactivĂ©e", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ParamĂštres", @@ -3468,13 +3668,25 @@ "messageformat": "Appel plein Ă©cran", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Afficher une vue en grille", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Modifier l'affichage", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Afficher la personne qui parle", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "En grille", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "LatĂ©rale", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Vue du prĂ©sentateur", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Vue modifiĂ©e", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Quitter l’appel", @@ -3576,6 +3788,14 @@ "messageformat": "Valider", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Impossible de modifier le message", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "{max,number} modifications seulement peuvent ĂȘtre appliquĂ©es Ă  ce message.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "DĂ©solĂ©, ce lien sgnl:// Ă©tait invalide", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nom d’utilisateur", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Une erreur s’est produite et votre nom d’utilisateur n’est plus associĂ© Ă  votre compte.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Supprimer le nom d’utilisateur", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "CrĂ©er un nom d’utilisateur", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Code QR ou lien", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Le nom d'utilisateur doit ĂȘtre rĂ©initialisĂ©", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Le lien d'utilisateur doit ĂȘtre rĂ©initialisĂ©", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Partagez votre pseudo", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Supprimer le nom d’utilisateur", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Cela supprimera votre nom d’utilisateur, permettant Ă  d’autres utilisateurs de le revendiquer. Confirmez-vous ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Cette action supprime votre nom d’utilisateur et dĂ©sactive votre lien et code QR. « {username} » pourra ensuite ĂȘtre utilisĂ© par un autre utilisateur. Êtes-vous sĂ»r de vouloir continuer ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Vous ne pourrez plus partager ou voir de Stories. Les nouveaux contenus rĂ©cemment ajoutĂ©s Ă  vos Stories seront Ă©galement supprimĂ©s.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Langue", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Langue", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Langue du systĂšme", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Rechercher une langue", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Aucun rĂ©sultat pour « {searchTerm} »", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "DĂ©finir", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "RedĂ©marrer Signal pour appliquer", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Pour changer de langue, l'application doit ĂȘtre redĂ©marrĂ©e.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "RedĂ©marrer", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Une mise Ă  jour vers la version {version} est proposĂ©e", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Une erreur est survenue lors de l’enregistrement de vos paramĂštres. Veuillez rĂ©essayer.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Message", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Plus de modes", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "RĂ©initialiser", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "TerminĂ©", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Couleur du lien associĂ© au nom d’utilisateur, {index,number} sur {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Si vous rĂ©initialisez votre code QR, votre lien et code QR existants ne fonctionneront plus.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "RĂ©initialisation du lien
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Le code QR et le lien ne sont pas dĂ©finis. Veuillez vĂ©rifier votre connexion rĂ©seau puis rĂ©essayez.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Configurer votre nom d’utilisateur Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "modifiĂ©", + "messageformat": "ModifiĂ©", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Envoyer de nouveau", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Davantage d’actions", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Appels", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nouvel appel", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nouvel appel", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Davantage d’actions", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Effacer l’historique des appels", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Effacer l’historique des appels ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Cette action supprimera l’historique des appels de maniĂšre permanente.", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "RĂ©initialiser", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Journal d'appels vidĂ©", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Cliquer pour voir ou dĂ©marrer un onglet", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Chercher", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Rechercher dans les appels manquĂ©s", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Activer/dĂ©sactiver", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Aucun appel rĂ©cent. Commencez en appelant un ami.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Aucun rĂ©sultat pour « {query} »", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Entrant", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Sortant", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ManquĂ©", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Appel de groupe", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Aucune conversation rĂ©cente.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Aucun rĂ©sultat pour « {query} »", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Appel vocal sortant} other {Appel vocal entrant}}} Video {{direction, select, Outgoing {Appel vidĂ©o sortant} other {Appel vidĂ©o entrant}}} Group {{direction, select, Outgoing {Appel de groupe sortant} other {Appel de groupe entrant}}} other {{direction, select, Outgoing {Appel sortant} other {Appel entrant}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Appel vocal manquĂ©} Video {Appel vidĂ©o manquĂ©} Group {Appel de groupe manquĂ©} other {Appel manquĂ©}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Appel vocal sans rĂ©ponse} Video {Appel vidĂ©o sans rĂ©ponse} Group {Appel de groupe sans rĂ©ponse} other {Appel sans rĂ©ponse}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Appel vocal rejetĂ©} Video {Appel vidĂ©o rejetĂ©} Group {Appel de groupe rejetĂ©} other {Appel rejetĂ©}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} autre personne est en train d’écrire.} other {{count,number} autres personnes sont en train d’écrire.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Les nouveautĂ©s", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Petits ajustements, corrections de bugs et amĂ©liorations des performances. Nous vous remercions d’utiliser Signal !", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Cette mise Ă  jour prĂ©voit des amĂ©liorations pour les appels vocaux et vidĂ©o, ainsi que pour la documentation (merci, {linkToGithub} !)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Vous pouvez dĂ©sormais modifier la langue sĂ©lectionnĂ©e dans Signal sans modifier les paramĂštres de votre systĂšme (ParamĂštres Signal > Apparence > Langue)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Nous avons mis Ă  jour les icĂŽnes de notification qui signalent des actualitĂ©s relatives aux conversations de groupe afin d’amĂ©liorer la lisibilitĂ© (particuliĂšrement pratique pour ceux qui prĂ©fĂšrent utiliser leur tĂ©lĂ©phone en mode sombre)." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Nous avons corrigĂ© un lĂ©ger retard parfois observĂ© lors d'appels sur des pĂ©riphĂ©riques macOS, soit une excuse de moins en cas de retard d'une demi-seconde Ă  votre prochaine rĂ©union." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Nous avons corrigĂ© l’animation de transition des tuiles lorsqu’un participant rejoint ou quitte l’appel de groupe. Lorsque le visage de votre ami se glisse dans votre champ de vision sur votre Ă©cran, on appelle ça un mouvement social." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Vous pouvez dĂ©sormais cliquer sur une photo de profil ou un avatar de groupe affichĂ©s dans l’en-tĂȘte d’une conversation pour accĂ©der rapidement aux paramĂštres de la conversation ou visionner les nouvelles Stories publiĂ©es dans cette conversation. Merci, {linkToGithub} !" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ga-IE/messages.json b/_locales/ga-IE/messages.json index 47f11c9cdb..1dc39208b8 100644 --- a/_locales/ga-IE/messages.json +++ b/_locales/ga-IE/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "EarrĂĄid leis an mBunachar SonraĂ­", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Tharla earrĂĄid leis an mbunachar sonraĂ­. Is fĂ©idir leat an earrĂĄid a chĂłipeĂĄil agus teagmhĂĄil a dhĂ©anamh le foireann tacaĂ­ochta Signal leis an bhfadhb a rĂ©iteach. MĂĄs gĂĄ duit Signal a ĂșsĂĄid dĂ­reach anois, is fĂ©idir leat do shonraĂ­ a scriosadh agus atosĂș air.\n\nNasc leis an bhfoireann tacaĂ­ochta: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Scrios na sonraĂ­ go lĂ©ir agus atosaigh", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Scrios sonraĂ­ agus atosaigh", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Scrios na sonraĂ­ ar fad go buan?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Scriosfar stair do theachtaireachtaĂ­ agus do mheĂĄn uile go buan Ăłn nglĂ©as seo. Beidh tĂș in ann Signal a ĂșsĂĄid ar an nglĂ©as seo tar Ă©is Ă© a athnascadh. NĂ­ scriosfar aon sonraĂ­ Ăł do ghuthĂĄn leis sin.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "NĂ­ hionann an leagan bunachair shonraĂ­ atĂĄ agat agus an leagan seo de Signal. Cinntigh go bhfuil an leagan is nuaĂ­ de Signal ĂĄ oscailt agat ar do rĂ­omhaire.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Comhad", @@ -300,6 +316,70 @@ "messageformat": "ComhrĂĄite", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "BhĂ­ fadhb le d'ainm ĂșsĂĄideora, nĂ­l sĂ© sannta do do chuntas a thuilleadh. Is fĂ©idir leat athshocrĂș a thriail nĂł ceann nua a roghnĂș.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Deisigh anois", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "BhĂ­ fadhb le do chĂłd QR agus nasc d'ainm ĂșsĂĄideora, nĂ­l sĂ© bailĂ­ a thuilleadh. Cruthaigh nasc nua lena chomhroinnt le daoine eile.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Deisigh anois", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "TaispeĂĄin TĂĄib", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Folaigh TĂĄib", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Tharla earrĂĄid", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} neamhlĂ©ite", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Sainithe mar neamhlĂ©ite", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ComhrĂĄite", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Glaonna", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ScĂ©alta", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Socruithe", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Nuashonraigh Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "PrĂłifĂ­l", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Ar Ais", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "TĂĄ na comhrĂĄite seo sa chartlann agus nĂ­ thaispeĂĄnfar sa Bhosca Isteach iad ach amhĂĄin mĂĄ fhaightear teachtaireachtaĂ­ nua.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Cuir glao air/uirthi mar sin fĂ©in", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "TĂ©igh isteach ar aon nĂłs", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continue Call", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "TĂĄ uimhreacha sĂĄbhĂĄilteachta ĂĄ nuashonrĂș.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Foghlaim tuilleadh", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Uimhir sĂĄbhĂĄilteachta roimhe seo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "An chĂ©ad uimhir sĂĄbhĂĄilteachta eile", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Leagan na huimhreach sĂĄbhĂĄilteachta, {index,number} as {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "MarcĂĄil 'Deimhnithe'", @@ -663,33 +747,41 @@ "messageformat": "Glan an deimhniĂș", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Chun criptiĂș Ăł cheann ceann le {name} a fhĂ­orĂș, cuir na huimhreacha thuas i gcomparĂĄid le glĂ©as an duine sin. Is fĂ©idir leis an duine eile do chĂłd a scanadh leis an nglĂ©as aige/aici freisin.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Tuilleadh faisnĂ©ise", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Chun criptiĂș Ăł cheann ceann le {name} a fhĂ­orĂș, meaitseĂĄil an cĂĄrta datha thuas le glĂ©as an duine sin agus cuir na huimhreacha i gcomparĂĄid lena chĂ©ile. Mura meaitseĂĄlann siad, triail an pĂ©ire eile uimhreacha sĂĄbhĂĄilteachta. NĂ­ gĂĄ ach pĂ©ire amhĂĄin a mheaitseĂĄil.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Chun criptiĂș Ăł cheann ceann le {name} a fhĂ­orĂș, cuir na huimhreacha thuas i gcomparĂĄid le glĂ©as an duine sin. Is fĂ©idir leis an duine eile do chĂłd a scanadh leis an nglĂ©as aige/aici freisin.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Athruithe ar Uimhreacha SĂĄbhĂĄilteachta", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "TĂĄ uimhreacha sĂĄbhĂĄilteachta ĂĄ nuashonrĂș thar thrĂ©imhse aistrithe le gnĂ©ithe prĂ­obhĂĄideachais atĂĄ ar na bacĂĄin a chumasĂș in Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Chun uimhreacha sĂĄbhĂĄilteachta a fhĂ­orĂș, meaitseĂĄil an cĂĄrta datha le glĂ©as do theagmhĂĄlaĂ­. Mura meaitseĂĄlann siad, triail an pĂ©ire eile uimhreacha sĂĄbhĂĄilteachta. NĂ­ gĂĄ ach pĂ©ire amhĂĄin a mheaitseĂĄil.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "An bhfuil cĂșnamh uait?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Tuigim", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "CruthĂłfar uimhir sĂĄbhĂĄilteachta leis an duine sin tar Ă©is duit teachtaireachtaĂ­ a sheoladh idir a chĂ©ile.", @@ -1267,10 +1359,6 @@ "messageformat": "FĂ©ach ar na meĂĄin le dĂ©anaĂ­", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Chun slĂĄndĂĄil do chriptithe Ăł cheann ceann le {name} a fhĂ­orĂș, cuir na huimhreacha thuas i gcomparĂĄid le glĂ©as an duine sin. Is fĂ©idir leis an duine eile an cĂłd QR thuas a scanadh freisin.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "NĂ­or sheol tĂș teachtaireachtaĂ­ chuig an duine seo nĂĄ nĂ­ bhfuair tĂș cinn uaidh/uaithi. Beidh d'uimhir sĂĄbhĂĄilteachta leis an duine sin ar fĂĄil tar Ă©is an chĂ©ad teachtaireacht." }, @@ -1334,17 +1422,17 @@ "messageformat": "Eolas", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Scrios", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Scrios teachtaireachtaĂ­", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Scrios comhrĂĄ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Scrios teachtaireachtaĂ­?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Scriosfar an comhrĂĄ seo Ăłn nglĂ©as seo.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Scriosfar teachtaireachtaĂ­ sa chomhrĂĄ seo Ăłn nglĂ©as seo. Beidh tĂș in ann cuardach le haghaidh an chomhrĂĄ seo tar Ă©is duit teachtaireachtaĂ­ a scriosadh.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Imigh as an ngrĂșpa", @@ -1438,6 +1526,14 @@ "messageformat": "TĂĄ do stair teachtaireachtaĂ­ don dĂĄ chomhrĂĄ cumasctha anseo.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "Is le {conversationTitle} {phoneNumber}. TĂĄ sibh beirt in bhur mball de {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "Is le {conversationTitle} {phoneNumber}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Mionsamhail Ă­omhĂĄ Ăłn teachtaireacht luaite", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Glaoigh ArĂ­s", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Tosaigh an glao", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "TĂ©igh isteach sa ghlao", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "BalbhaĂ­odh an micreafĂłn mar gheall ar mhĂ©id an ghlao", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "FĂłgraĂ­ maidir le glaonna", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Call is Full", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Ceamara", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "TĂ©igh isteach ann", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Tosaigh", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Glao lĂĄn", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Ceamara dĂ­chumasaithe", @@ -1621,10 +1725,6 @@ "messageformat": "Cas air an ceamara", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Balbhaigh", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "MicreafĂłn dĂ­chumasaithe", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "DĂ­bhalbhaigh an micreafĂłn", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Comhroinn", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Comhroinnt scĂĄileĂĄin dĂ­chumasaithe", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Stop comhroinnt scĂĄileĂĄin", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Glaoigh", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "TĂĄ an grĂșpa rĂł-mhĂłr le glao a chur ar na rannphĂĄirtithe.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Cumasaigh bualadh", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Cas as glaoch", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Cas air glaoch", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Tuilleadh roghanna", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Tusa", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Your camera is off", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "FĂ©ach ar an Uimhir ShĂĄbhĂĄilteachta", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Seol teachtaireacht", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "FĂ©ach ar an Uimhir ShĂĄbhĂĄilteachta", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Theip ar an uimhir ghuthĂĄin a fhĂĄil. SeiceĂĄil do nasc agus triail arĂ­s.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "NĂ­ fĂ©idir eagarthĂłireacht a chur i bhfeidhm ach amhĂĄin laistigh de 3 uair an chloig Ăłn uair a sheol tĂș an teachtaireacht seo.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "NĂ­ fĂ©idir eagarthĂłireacht a chur i bhfeidhm ach amhĂĄin laistigh de 24 uair an chloig Ăłn uair a sheol tĂș an teachtaireacht seo.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Scriosadh an teachtaireacht seo.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "TĂĄ an ceangaltĂĄn rĂłmhĂłr lena thaispeĂĄint.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "TĂĄ roinnt ceangaltĂĄn rĂłmhĂłr lena dtaispeĂĄint.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "NĂ­ fĂ©idir sonraĂ­ an tabhartais a fhĂĄil", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Leagan bĂ©ite Signal amhĂĄin", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "NĂ­l cur teachtaireachtaĂ­ in eagar ar fĂĄil ach ag bĂ©ite-ĂșsĂĄideoirĂ­ Signal. MĂĄ chuirfidh tĂș teachtaireacht in eagar, nĂ­ fheicfidh ach na daoine a bhfuil an leagan is dĂ©anaĂ­ de Signal acu Ă©.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Cuir Teachtaireacht in Eagar", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "MĂĄ chuirfidh tĂș teachtaireacht in eagar, nĂ­ fheicfidh ach na daoine a bhfuil na leaganacha is dĂ©anaĂ­ de Signal acu Ă­. Feicfidh siad gur chuir tĂș teachtaireacht in eagar.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "FĂ­sghlao isteach
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Guthghlao amach", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "FĂ­sghlao amach", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "TĂĄ {ringer}ag glaoch ort", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Athnascadh
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} duine} two {{count,number} dhuine} few {{count,number} dhuine} many {{count,number} nduine} other {{count,number} duine}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Guthghlao", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Cuir deireadh leis", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Imigh as", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "MicreafĂłn as", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "MicreafĂłn air", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Glaoch air", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Glaoch as", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Socruithe", @@ -3468,13 +3668,25 @@ "messageformat": "Cuir an glao i mĂłd lĂĄnscĂĄileĂĄin", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Aistrigh chuig amharc greille", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Athraigh amharc", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Aistrigh chuig amharc cainteoirĂ­", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Amharc greille", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Amharc taobh-bharra", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Amharc cainteora", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Amharc nuashonruithe", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Leave Call", @@ -3576,6 +3788,14 @@ "messageformat": "TĂĄ go maith", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "NĂ­ fĂ©idir an teachtaireacht a chur in eagar", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "NĂ­ fĂ©idir ach {max,number} n-eagarthĂłireacht a dhĂ©anamh ar an teachtaireacht seo.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Ár leithscĂ©al, nĂ­ raibh ciall leis an nasc sgnl:// sin!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Ainm ĂșsĂĄideora", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "BhĂ­ fadhb le d'ainm ĂșsĂĄideora, nĂ­l sĂ© sannta do do chuntas a thuilleadh.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Scrios ainm ĂșsĂĄideora", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Cruthaigh Ainm ÚsĂĄideora", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "CĂłd QR nĂł Nasc", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "NĂ­ mĂłr an t-ainm ĂșsĂĄideora a athshocrĂș", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "NĂ­ mĂłr nasc an ainm ĂșsĂĄideora a athshocrĂș", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Comhroinn d'Ainm ÚsĂĄideora", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Scrios ainm ĂșsĂĄideora", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Bainfear d'ainm ĂșsĂĄideora leis sin, rud a ligfidh d'ĂșsĂĄideoirĂ­ eile Ă© a Ă©ileamh. Cinnte?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Bainfear d'ainm ĂșsĂĄideora agus dĂ­chumasĂłfar do chĂłd QR agus nasc leis sin. Beidh “{username}” ar fĂĄil ag daoine eile le hĂ©ileamh. An bhfuil tĂș cinnte?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "NĂ­ bheidh tĂș in ann fĂ©achaint ar scĂ©alta nĂĄ iad a chomhroinnt a thuilleadh. Chomh maith leis sin, scriosfar na nuashonruithe scĂ©il a chomhroinn tĂș le dĂ©anaĂ­.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Teanga", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Teanga", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Teanga an ChĂłrais", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Cuardaigh teangacha", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "NĂ­ bhfuarthas aon torthaĂ­ ar \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Socraigh", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Atosaigh Signal lena cur i bhfeidhm", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Chun an teanga a athrĂș, nĂ­ mĂłr an aip a atosĂș.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Atosaigh", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "NuashonrĂș chuig an leagan {version} ar fĂĄil", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Tharla earrĂĄid agus do shocruithe ĂĄ sĂĄbhĂĄil. Triail arĂ­s.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Teachtaireacht", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Tuilleadh stĂ­leanna", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Athshocraigh", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "DĂ©anta", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Dath naisc ainm ĂșsĂĄideora, {index,number} as {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "MĂĄ athshocraĂ­onn tĂș do chĂłd QR, nĂ­ oibreoidh an cĂłd QR nĂĄ an nasc atĂĄ agat cheana fĂ©in a thuilleadh.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Nasc ĂĄ athshocrĂș...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "NĂ­or socraĂ­odh an cĂłd QR nĂĄ nasc. SeiceĂĄil do nasc lĂ­onra agus triail arĂ­s.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Socraigh d'ainm ĂșsĂĄideora Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "arna cur in eagar", + "messageformat": "Curtha in eagar", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Seol ArĂ­s", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Tuilleadh gnĂ­omhartha", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Glaonna", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Glao nua", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Glao nua", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Tuilleadh gnĂ­omhartha", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Glan stair na nglaonna", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Glan stair na nglaonna?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Scriosfar stair na nglaonna uile leis sin", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Glan", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Stair na nglaonna glanta", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "CliceĂĄil le fĂ©achaint ar ghlao nĂł le tosĂș air", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Cuardaigh", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Scag de rĂ©ir caillte", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ScorĂĄnaigh", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "NĂ­l glaonna le dĂ©anaĂ­ ann. Glaoigh ar chara le tosĂș air.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "NĂ­l aon torthaĂ­ ar “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Isteach", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Amach", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Caillte", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Glao grĂșpa", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "NĂ­ comhrĂĄite le dĂ©anaĂ­ ann.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "NĂ­l aon torthaĂ­ ar “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Guthghlao amach} other {Guthghlao isteach}}} Video {{direction, select, Outgoing {FĂ­sghlao amach} other {FĂ­sghlao isteach}}} Group {{direction, select, Outgoing {GrĂșpghlao amach} other {GrĂșpghlao isteach}}} other {{direction, select, Outgoing {Glao amach} other {Glao isteach}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Guthghlao caillte} Video {FĂ­sghlao caillte} Group {GrĂșpghlao caillte} other {Glao caillte}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Guthghlao nĂĄr freagraĂ­odh} Video {FĂ­sghlao nĂĄr freagraĂ­odh} Group {GrĂșpghlao nĂĄr freagraĂ­odh} other {Glao nĂĄr freagraĂ­odh}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Guthghlao a diĂșltaĂ­odh dĂł} Video {FĂ­sghlao a diĂșltaĂ­odh dĂł} Group {GrĂșpghlao a diĂșltaĂ­odh dĂł} other {Glao a diĂșltaĂ­odh dĂł}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {TĂĄ {count,number} duine eile ag clĂłscrĂ­obh.} two {TĂĄ {count,number} dhuine eile ag clĂłscrĂ­obh.} few {TĂĄ {count,number} dhuine eile ag clĂłscrĂ­obh.} many {TĂĄ {count,number} nduine eile ag clĂłscrĂ­obh.} other {TĂĄ {count,number} duine eile ag clĂłscrĂ­obh.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Cad AtĂĄ Nua", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Mionathruithe, paistĂ­ fabhtanna agus feabhsuithe ar fheidhmĂ­ocht. Go raibh maith agat as Signal a ĂșsĂĄid!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ÁirĂ­tear sa nuashonrĂș seo roinnt feabhsuithe do ghuthghlaonna agus fĂ­sghlaonna, agus roinnt mion-nuashonruithe ar dhoicimĂ©adĂșchĂĄn (buĂ­ochas leat, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Anois is fĂ©idir leat do theanga roghnaithe a athrĂș in Signal gan socruithe do chĂłrais a athrĂș (Socruithe Signal > Cuma > Teanga)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Rinneamar roinnt deilbhĂ­nĂ­ fĂłgraĂ­ grĂșpa a nuashonrĂș." + "icu:WhatsNew__v6.39--1": { + "messageformat": "RĂ©itĂ­omar moill bheag a tharla corruair ar macOS tar Ă©is dul isteach i nglao." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "RĂ©itĂ­omar an bheochan trasdula do theidil fĂ­seĂĄn nuair a thĂ©ann duine isteach i ngrĂșpghlao nĂł nuair a imĂ­onn duine as." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Anois is fĂ©idir leat cliceĂĄil ar ghrianghraf prĂłifĂ­le nĂł ar abhatĂĄr an ghrĂșpa i gceanntĂĄsc an chomhrĂĄ le socruithe comhrĂĄ a rochtain go tapa nĂł le fĂ©achaint ar aon scĂ©al nach bhfaca tĂș Ăłn gcomhrĂĄ sin. Le buĂ­ochas, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/gl-ES/messages.json b/_locales/gl-ES/messages.json index 52172cc393..c0c49cf88c 100644 --- a/_locales/gl-ES/messages.json +++ b/_locales/gl-ES/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Erro da base de datos", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ocorreu un erro na base de datos. Podes copiar o erro e contactar co Centro de axuda de Signal para solucionar o problema. Se tes que empregar Signal canto antes, podes borrar os teus datos e reiniciar.\n\nPara contactar co Centro de axuda visita: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Eliminar todos os datos e reiniciar", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Borrar datos e reiniciar", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Borrar de forma permanente todos os datos?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Toda a tĂșa historia de mensaxes e arquivos multimedia borraranse para sempre neste dispositivo. PoderĂĄs empregar Signal de novo neste dispositivo despois de vinculalo outra vez. Isto non eliminarĂĄ nada do teu telĂ©fono.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "A versiĂłn da tĂșa base de datos non coincide con esta versiĂłn de Signal. AsegĂșrate de abrir a Ășltima versiĂłn de Signal no teu ordenador.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Ficheiro", @@ -300,6 +316,70 @@ "messageformat": "Conversas", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Algo saĂ­u mal co teu nome de usuario, xa non estĂĄ asignado ĂĄ tĂșa conta. Podes probar e configuralo de novo ou elixir un novo.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Corrixir", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Algo saĂ­u mal co teu cĂłdigo QR e coa ligazĂłn de nome de usuario. Xa non son vĂĄlidos. Crea unha nova ligazĂłn para compartir cos demais.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Corrixir", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Mostrar lapelas", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ocultar lapelas", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Algo saĂ­u mal", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} sen ler", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marcar como sen ler", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Conversas", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Chamadas", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Historias", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ConfiguraciĂłn", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Actualizar Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Perfil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Volver", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Estas conversas estĂĄn arquivadas asĂ­ que sĂł aparecerĂĄn na caixa de entrada cando cheguen novas mensaxes.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Chamar igualmente", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Unirse igualmente", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continuar a chamada", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Imos actualizar os nĂșmero de seguranza.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Saber mĂĄis", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Anterior nĂșmero de seguranza", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Seguinte nĂșmero de seguranza", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "VersiĂłn de nĂșmero de seguranza, {index,number} de {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marcar como verificado", @@ -663,33 +747,41 @@ "messageformat": "Borrar verificaciĂłn", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Para verificar a encriptaciĂłn de extremo a extremo con {name}, compara os nĂșmeros de mĂĄis arriba co seu dispositivo. TamĂ©n poden escanear o teu cĂłdigo co seu dispositivo.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Saber mĂĄis", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Para verificar a encriptaciĂłn de extremo a extremo con {name}, emparella a cor da tarxeta que se amosa co seu dispositivo e compara os nĂșmeros. Se non coinciden, proba outro par de nĂșmeros de seguranza. SĂł Ă© necesario que unha parella de nĂșmeros coincida.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Para verificar a encriptaciĂłn de extremo a extremo con {name}, compara os nĂșmeros de mĂĄis arriba co seu dispositivo. TamĂ©n poden escanear o teu cĂłdigo co seu dispositivo.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Cambios nos nĂșmeros de seguranza", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Durante unha fase de transiciĂłn, actualizaremos os nĂșmeros de seguranza para permitir a configuraciĂłn da futura funciĂłn de seguridade en Signal.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Para verificar os nĂșmeros de seguranza, tes que emparellar a cor da tarxeta co dispositivo do teu contacto. Se non coinciden, proba outro par de nĂșmeros de seguranza. SĂł Ă© necesario que unha parella de nĂșmeros coincida.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Necesitas axuda?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Entendo", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Crearase un nĂșmero de seguranza con esta persoa despois de que intercambie mensaxes contigo.", @@ -1267,10 +1359,6 @@ "messageformat": "Ver contido multimedia recente", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Para verificar a seguranza da tĂșa encriptaciĂłn de extremo a extremo con {name}, compara os nĂșmeros de mĂĄis arriba co seu dispositivo. TamĂ©n poden escanear o cĂłdigo QR.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "You haven't exchanged any messages with this contact yet. Your safety number with them will be available after the first message." }, @@ -1334,17 +1422,17 @@ "messageformat": "InformaciĂłn", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Eliminar", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Borrar mensaxes", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Borrar conversa?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Borrar mensaxes?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Esta conversa borrarase deste dispositivo.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "As mensaxes desta conversa eliminaranse deste dispositivo. Podes buscar esta conversa despois de eliminar as mensaxes.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Abandonar grupo", @@ -1438,6 +1526,14 @@ "messageformat": "O teu historial de mensaxes para ambas conversas xuntouse aquĂ­.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pertence a {conversationTitle}. Ámbolos dous sodes membros de {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pertence a {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura da imaxe da mensaxe citada", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Volver chamar", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Iniciar chamada", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Unirse ĂĄ chamada", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Silenciouse o micrĂłfono debido ao nĂșmero de persoas na chamada", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "NotificaciĂłns de chamadas", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "A chamada estĂĄ completa", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "CĂĄmara", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Unirse", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Comezar", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Chamada completa", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "CĂĄmara desactivada", @@ -1621,10 +1725,6 @@ "messageformat": "Encender a cĂĄmara", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silenciar", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "MicrĂłfono desactivado", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Activar micro", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Compartir", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PresentaciĂłn desactivada", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Parar presentaciĂłn", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Chamar", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "O grupo Ă© demasiado grande para chamar a todos os membros.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Activar son", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Desactivar son da chamada", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Activar son da chamada", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "MĂĄis opciĂłns", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Ti", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "A cĂĄmara estĂĄ apagada", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Ver nĂșmero de seguranza", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mensaxe", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Ver nĂșmero de seguranza", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Erro ao buscar o nĂșmero de telĂ©fono. Comproba a tĂșa conexiĂłn e intĂ©ntao de novo.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "As ediciĂłns sĂł poden facerse no termo de 3 horas dende que se enviou a mensaxe.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "As ediciĂłns sĂł poden facerse no termo de 24 horas dende que se enviou esta mensaxe.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Eliminouse a mensaxe.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "O anexo Ă© demasiado grande para mostrarse.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "AlgĂșns anexos son demasiado grandes para mostralos.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Erro ao compilar os detalles da doazĂłn", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "SĂł para versiĂłn beta de Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Editar mensaxes sĂł estĂĄ dispoñible para usuarios da versiĂłn beta de Signal. Se editas unha mensaxe, sĂł serĂĄ visible para as persoas que teñan a Ășltima versiĂłn beta de Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editar mensaxe", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Se editas unha mensaxe, sĂł serĂĄ visible para as persoas que teñan as Ășltimas versiĂłns de Signal. PoderĂĄn ver que editaches a mensaxe.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Chamada de vĂ­deo entrante
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Chamada de voz saĂ­nte", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Chamada saĂ­nte de vĂ­deo", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "ChĂĄmate {ringer}", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Volvendo conectar
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "{duration} de Signal", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number}persoa} other {{count,number} persoas}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Chamada de voz", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Finalizar", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Abandonar", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Micro desactivado", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Micro activado", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Son da chamada activado", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Son da chamada desactivado", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ConfiguraciĂłn", @@ -3468,13 +3668,25 @@ "messageformat": "Chamada a pantalla completa", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Trocar a vista de cuadrĂ­cula", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Cambiar vista", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Cambiar a vista de orador", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Vista de grella", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Vista lateral", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Vista de falante", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Modo de visualizaciĂłn actualizado", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Deixar a chamada", @@ -3576,6 +3788,14 @@ "messageformat": "De acordo", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Non se pode editar a mensaxe", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "SĂł se pode editar esta mensaxe {max,number} veces.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Agarda! Esa ligazĂłn sgnl:// non ten sentido!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nome de usuario", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Algo saĂ­u mal co teu nome de usuario, xa non estĂĄ asignado ĂĄ tĂșa conta.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Borrar nome de usuario", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Crear nome de usuario", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "CĂłdigo QR ou ligazĂłn", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "O nome de usuario ten que restablecerse", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "A ligazĂłn do nome de usuario ten que restablecerse", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Comparte o teu nome de usuario", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Borrar nome de usuario", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Eliminarase o teu nome de usuario e outros usuarios poderĂĄn utilizalo. EstĂĄs seguro?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Isto eliminarĂĄ o teu nome de usuario e desactivarĂĄ o teu cĂłdigo QR e ligazĂłn. «{username}» estarĂĄ dispoñible para que outros usuarios poidan utilizalo. Queres continuar?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Xa non poderĂĄs compartir ou ver historias. Eliminaranse tamĂ©n as novas historias que compartiches.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Idioma", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Idioma", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Idioma do sistema", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Buscar idiomas", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "NingĂșn resultado para «{searchTerm}»", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Fixar", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Reiniciar Signal para aplicar", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Para cambiar o idioma, a aplicaciĂłn debe reiniciarse.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Reiniciar", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Actualizar ĂĄ versiĂłn dispoñible {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Ocorreu un erro ao gardar a configuraciĂłn. IntĂ©ntao de novo.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mensaxe", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "MĂĄis estilos", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Restablecer", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Feito", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Cor da ligazĂłn do nome de usuario, {index,number} de {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Se restableces o teu cĂłdigo QR, tanto o cĂłdigo antigo como a ligazĂłn xa non funcionarĂĄn.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Restablecendo ligazĂłn...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "O cĂłdigo QR e a ligazĂłn non se estableceron. Comproba a tĂșa conexiĂłn a Internet e intĂ©ntao de novo.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Configura o teu nome de usuario de Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editada", + "messageformat": "Editada", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Enviar de novo", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "MĂĄis acciĂłns", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Chamadas", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nova chamada", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nova chamada", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "MĂĄis acciĂłns", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Baleirar historial de chamadas", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Baleirar historial de chamadas?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Isto borrarĂĄ o historial de chamadas de xeito permanente", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Despexar", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Historial de chamadas eliminado", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Premer para ver ou comezar unha chamada", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Buscar", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrar por perdidas", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Cambiar", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Sen chamadas recentes. Comeza chamando a un amigo.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "NingĂșn resultado para «{query}»", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Entrante", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "SaĂ­nte", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Perdida", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Chamada en grupo", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Sen conversas recentes.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "NingĂșn resultado para «{query}»", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Chamada de voz saĂ­nte} other {Chamada de voz entrante}}} Video {{direction, select, Outgoing {Chamada saĂ­nte de vĂ­deo} other {Chamada entrante de vĂ­deo}}} Group {{direction, select, Outgoing {Chamada de grupo saĂ­nte} other {Chamada de grupo entrante}}} other {{direction, select, Outgoing {Chamada saĂ­nte} other {Chamada recibida}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Chamada de voz perdida} Video {Chamada perdida de vĂ­deo} Group {Chamada de grupo perdida} other {Chamada perdida}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Chamada de voz non respondida} Video {Chamada de vĂ­deo non respondida} Group {Chamada de grupo non respondida} other {Chamada non respondida}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Chamada de voz rexeitada} Video {Videochamada rexeitada} Group {Chamada de grupo rexeitada} other {Chamada rexeitada}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} outro estĂĄ a escribir.} other {{count,number} outros estĂĄn a escribir.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Novidades", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Comprende pequenas modificaciĂłns e melloras no rendemento. Moitas grazas por empregar Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Esta actualizaciĂłn inclĂșe melloras nas chamadas de voz e vĂ­deo, e unhas pequenas actualizaciĂłns na documentaciĂłn (grazas, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Agora podes cambiar o idioma que seleccionaches para Signal sen ter que cambiar a configuraciĂłn do sistema (ConfiguraciĂłn de Signal > PersonalizaciĂłn > Idioma)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Modificamos algunhas iconas de notificaciĂłn que aparecen nas actualizaciĂłns de grupos." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Arranxamos un pequeno atraso que se producĂ­a ĂĄs veces ao unirse a unha chamada dende un dispositivo macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Corriximos a animaciĂłn de transiciĂłn dos mosaicos dos vĂ­deos cando alguĂ©n se une ou abandona unha chamada de grupo." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Agora podes premer a foto de perfil ou avatar dun grupo na cabeceira da conversa para acceder de forma rĂĄpida ĂĄ sĂșa configuraciĂłn ou ver as historias pendentes desa conversa. Grazas, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/gu-IN/messages.json b/_locales/gu-IN/messages.json index cc49d33d73..d2567756d9 100644 --- a/_locales/gu-IN/messages.json +++ b/_locales/gu-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àȘĄà«‡àȘŸàȘŸàȘŹà«‡àȘàȘšà«€ àȘ–àȘŸàȘźà«€", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àȘĄà«‡àȘŸàȘŸàȘŹà«‡àȘ àȘàȘ°àȘ° àȘ†àȘ”ી. àȘ€àȘźà«‡ àȘàȘ°àȘ°àȘšà«‡ àȘ•ૉàȘȘàȘż àȘ•àȘ°à«€ àȘ…àȘšà«‡ àȘžàȘźàȘžà«àȘŻàȘŸàȘšà«‡ àȘ‰àȘ•ેàȘČàȘ”àȘŸàȘźàȘŸàȘ‚ àȘźàȘŠàȘŠ àȘźàȘŸàȘŸà«‡ Signal àȘžàȘȘોàȘ°à«àȘŸàȘšà«‹ àȘžàȘ‚àȘȘàȘ°à«àȘ• àȘ•àȘ°à«€ àȘ¶àȘ•à«‹ àȘ›à«‹. àȘœà«‹ àȘ€àȘźàȘŸàȘ°à«‡ àȘ€àȘ°àȘ€ àȘœ SignalàȘšà«‹ àȘ‰àȘȘàȘŻà«‹àȘ— àȘ•àȘ°àȘ”àȘŸàȘšà«€ àȘœàȘ°à«‚àȘ° àȘčોàȘŻ, àȘ€à«‹ àȘ€àȘźà«‡ àȘ€àȘźàȘŸàȘ°à«‹ àȘĄà«‡àȘŸàȘŸ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«€àȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘ¶àȘ°à«‚ àȘ•àȘ°à«€ àȘ¶àȘ•à«‹ àȘ›à«‹.\n\nàȘ† àȘČàȘżàȘ‚àȘ• àȘȘàȘ° àȘœàȘˆàȘšà«‡ àȘžàȘȘોàȘ°à«àȘŸàȘšà«‹ àȘžàȘ‚àȘȘàȘ°à«àȘ• àȘ•àȘ°à«‹: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àȘŹàȘ§à«‹ àȘĄà«‡àȘŸàȘŸ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«€àȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘ¶àȘ°à«‚ àȘ•àȘ°à«‹", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àȘĄà«‡àȘŸàȘŸ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«‹ àȘ…àȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘ¶àȘ°à«‚ àȘ•àȘ°à«‹", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àȘŹàȘ§àȘŸ àȘĄà«‡àȘŸàȘŸ àȘ•àȘŸàȘŻàȘźà«€àȘ°à«‚àȘȘે àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ”àȘŸ àȘ›à«‡?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àȘ€àȘźàȘŸàȘ°à«€ àȘŹàȘ§à«€ àȘźà«‡àȘžà«‡àȘœ àȘčàȘżàȘžà«àȘŸà«àȘ°à«€ àȘ…àȘšà«‡ àȘźà«€àȘĄàȘżàȘŻàȘŸ àȘ† àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘȘàȘ°àȘ„ી àȘ•àȘŸàȘŻàȘźà«€àȘ°à«‚àȘȘે àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”àȘ¶à«‡. àȘ€àȘźà«‡ àȘ† àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘȘàȘ° SignalàȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘČàȘżàȘ‚àȘ• àȘ•àȘ°à«àȘŻàȘŸ àȘȘàȘ›à«€ àȘœ àȘ€à«‡àȘšà«‹ àȘ‰àȘȘàȘŻà«‹àȘ— àȘ•àȘ°à«€ àȘ¶àȘ•àȘ¶à«‹. àȘ† àȘ€àȘźàȘŸàȘ°àȘŸ àȘ«à«‹àȘšàȘźàȘŸàȘ‚àȘ„ી àȘ•à«‹àȘˆ àȘȘàȘŁ àȘĄà«‡àȘŸàȘŸàȘšà«‡ àȘĄàȘżàȘČીàȘŸ àȘšàȘčીàȘ‚ àȘ•àȘ°à«‡.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àȘ€àȘźàȘŸàȘ°àȘŸ àȘĄà«‡àȘŸàȘŸàȘŹà«‡àȘàȘšà«àȘ‚ àȘ”àȘ°à«àȘàȘš SignalàȘšàȘŸ àȘ† àȘ”àȘ°à«àȘàȘš àȘžàȘŸàȘ„ે àȘźà«‡àȘš àȘ„àȘ€à«àȘ‚ àȘšàȘ„ી. àȘ–àȘŸàȘ€àȘ°à«€ àȘ•àȘ°à«‹ àȘ•ે àȘ€àȘźà«‡ àȘ€àȘźàȘŸàȘ°àȘŸ àȘ•àȘźà«àȘȘ્àȘŻà«‚àȘŸàȘ° àȘȘàȘ° SignalàȘšà«àȘ‚ àȘČેàȘŸà«‡àȘžà«àȘŸ àȘ”àȘ°à«àȘàȘš àȘ–à«‹àȘČી àȘ°àȘč્àȘŻàȘŸàȘ‚ àȘ›à«‹.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&àȘ«àȘŸàȘ‡àȘČ", @@ -300,6 +316,70 @@ "messageformat": "àȘšà«‡àȘŸ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àȘ€àȘźàȘŸàȘ°àȘŸ àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘžàȘŸàȘ„ે àȘ•àȘ‚àȘˆàȘ• àȘ–à«‹àȘŸà«àȘ‚ àȘ„àȘŻà«àȘ‚ àȘ›à«‡, àȘ€à«‡ àȘčàȘ”ે àȘ€àȘźàȘŸàȘ°àȘŸ àȘàȘ•àȘŸàȘ‰àȘšà«àȘŸàȘšà«‡ àȘžà«‹àȘ‚àȘȘàȘŸàȘŻà«‡àȘČુàȘ‚ àȘšàȘ„ી. àȘ€àȘźà«‡ àȘ€à«‡àȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘžà«‡àȘŸ àȘ•àȘ°àȘ”àȘŸàȘšà«‹ àȘȘ્àȘ°àȘŻàȘŸàȘž àȘ•àȘ°à«€ àȘ¶àȘ•à«‹ àȘ›à«‹ àȘ…àȘ„àȘ”àȘŸ àȘšàȘ”ુàȘ‚ àȘȘàȘžàȘ‚àȘŠ àȘ•àȘ°à«€ àȘ¶àȘ•à«‹ àȘ›à«‹.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àȘ…àȘ€à«àȘŻàȘŸàȘ°à«‡ àȘ à«€àȘ• àȘ•àȘ°à«‹", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àȘ€àȘźàȘŸàȘ°àȘŸ QR àȘ•à«‹àȘĄ àȘ…àȘšà«‡ àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘČàȘżàȘ‚àȘ• àȘžàȘŸàȘ„ે àȘ•àȘ‚àȘˆàȘ• àȘ–à«‹àȘŸà«àȘ‚ àȘ„àȘŻà«àȘ‚ àȘ›à«‡, àȘ€à«‡ àȘčàȘ”ે àȘźàȘŸàȘšà«àȘŻ àȘšàȘ„ી. àȘ…àȘšà«àȘŻ àȘČોàȘ•à«‹ àȘžàȘŸàȘ„ે àȘ¶à«‡àȘ° àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡ àȘšàȘ”ી àȘČàȘżàȘ‚àȘ• àȘŹàȘšàȘŸàȘ”ો.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àȘ…àȘ€à«àȘŻàȘŸàȘ°à«‡ àȘ à«€àȘ• àȘ•àȘ°à«‹", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àȘŸà«‡àȘŹ àȘŹàȘ€àȘŸàȘ”ો", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àȘŸà«‡àȘŹ àȘ›à«àȘȘàȘŸàȘ”ો", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àȘàȘ• àȘ­à«‚àȘČ àȘ†àȘ”ી", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} àȘš àȘ”àȘ‚àȘšàȘŸàȘŻà«‡àȘČ", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àȘš àȘ”àȘŸàȘ‚àȘšà«‡àȘČ àȘ€àȘ°à«€àȘ•ે àȘźàȘŸàȘ°à«àȘ• àȘ•àȘ°à«‹", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àȘšà«‡àȘŸ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àȘ•ૉàȘČ્àȘž", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àȘžà«àȘŸà«‹àȘ°à«€", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àȘžà«‡àȘŸàȘżàȘ‚àȘ—્àȘž", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal àȘšà«‡ àȘ…àȘȘàȘĄà«‡àȘŸ àȘ•àȘ°à«‹", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àȘȘ્àȘ°à«‹àȘ«àȘŸàȘˆàȘČ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àȘȘàȘŸàȘ›àȘł", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àȘ† àȘšà«‡àȘŸ àȘ†àȘ°à«àȘ•àȘŸàȘ‡àȘ” àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”ી àȘ›à«‡ àȘ…àȘšà«‡ àȘœà«‹ àȘšàȘ”àȘŸ àȘźà«‡àȘžà«‡àȘœ àȘȘ્àȘ°àȘŸàȘȘ્àȘ€ àȘ„àȘŸàȘŻ àȘ€à«‹ àȘœ àȘ‡àȘšàȘŹà«‹àȘ•્àȘžàȘźàȘŸàȘ‚ àȘŠà«‡àȘ–àȘŸàȘ¶à«‡.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àȘ•à«‹àȘˆàȘȘàȘŁ àȘ°à«€àȘ€à«‡ àȘ«à«‹àȘš àȘ•àȘ°à«‹", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àȘ€à«‹ àȘȘàȘŁ àȘœà«‹àȘĄàȘŸàȘ“", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àȘ•ૉàȘČ àȘšàȘŸàȘČુ àȘ°àȘŸàȘ–à«‹", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ° àȘ…àȘȘàȘĄà«‡àȘŸ àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”ી àȘ°àȘč્àȘŻàȘŸàȘ‚ àȘ›à«‡.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àȘ”àȘ§à« àȘ¶à«€àȘ–à«‹", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àȘ…àȘ—àȘŸàȘ‰àȘšà«‹ àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àȘ†àȘ—àȘŸàȘźà«€ àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ° àȘ”àȘ°à«àȘàȘš, {total,number}àȘźàȘŸàȘ‚àȘ„ી {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àȘšàȘ•àȘŸàȘžàȘŸàȘŻà«‡àȘČ àȘ€àȘ°à«€àȘ•ે àȘźàȘŸàȘ°à«àȘ• àȘ•àȘ°à«‹", @@ -663,33 +747,41 @@ "messageformat": "àȘšàȘ•àȘŸàȘžàȘŁà«€ àȘŠà«‚àȘ° àȘ•àȘ°à«‹", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} àȘžàȘŸàȘ„ે àȘ€àȘźàȘŸàȘ°àȘŸ àȘàȘšà«àȘĄ-àȘŸà«‚-àȘàȘšà«àȘĄ àȘàȘšà«àȘ•્àȘ°àȘżàȘȘ્àȘ¶àȘšàȘšà«€ àȘ–àȘŸàȘ€àȘ°à«€ àȘ•àȘ°àȘ”àȘŸ, àȘ‰àȘȘàȘ° àȘŠàȘ°à«àȘ¶àȘŸàȘ”ેàȘČàȘŸ àȘšàȘ‚àȘŹàȘ° àȘ€à«‡àȘźàȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘžàȘŸàȘ„ે àȘžàȘ°àȘ–àȘŸàȘ”ો. àȘ€à«‡àȘ“ àȘ€à«‡àȘźàȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘžàȘ„ી àȘȘàȘŁ àȘ€àȘźàȘŸàȘ°à«‹ àȘ•à«‹àȘĄ àȘžà«àȘ•ેàȘš àȘ•àȘ°à«€ àȘ¶àȘ•ે àȘ›à«‡.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àȘ”àȘ§à« àȘ¶à«€àȘ–à«‹", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} àȘžàȘŸàȘ„ે àȘ€àȘźàȘŸàȘ°àȘŸ àȘàȘšà«àȘĄ-àȘŸà«‚-àȘàȘšà«àȘĄ àȘàȘšà«àȘ•્àȘ°àȘżàȘȘ્àȘ¶àȘšàȘšà«€ àȘžà«àȘ°àȘ•્àȘ·àȘŸàȘšà«€ àȘ–àȘŸàȘ€àȘ°à«€ àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡, àȘ‰àȘȘàȘ° àȘŠàȘ°à«àȘ¶àȘŸàȘ”ેàȘČ àȘ•àȘČàȘ° àȘ•àȘŸàȘ°à«àȘĄàȘšà«‡ àȘ€à«‡àȘźàȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘžàȘŸàȘ„ે àȘźà«‡àȘš àȘ•àȘ°à«‹ àȘ…àȘšà«‡ àȘšàȘ‚àȘŹàȘ°àȘšà«€ àȘžàȘŸàȘ„ે àȘžàȘ°àȘ–àȘŸàȘ”ો. àȘœà«‹ àȘ† àȘźà«‡àȘš àȘš àȘ„àȘ€àȘŸàȘ‚ àȘčોàȘŻ, àȘ€à«‹ àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°à«‹àȘšà«€ àȘŹà«€àȘœà«€ àȘœà«‹àȘĄà«€ àȘ…àȘœàȘźàȘŸàȘ”ી àȘœà«àȘ“. àȘ«àȘ•્àȘ€ àȘàȘ• àȘœ àȘœà«‹àȘĄà«€ àȘźà«‡àȘš àȘ•àȘ°àȘ”àȘŸàȘšà«€ àȘœàȘ°à«‚àȘ° àȘ›à«‡.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} àȘžàȘŸàȘ„ે àȘ€àȘźàȘŸàȘ°àȘŸ àȘàȘšà«àȘĄ-àȘŸà«‚-àȘàȘšà«àȘĄ àȘàȘšà«àȘ•્àȘ°àȘżàȘȘ્àȘ¶àȘšàȘšà«€ àȘ–àȘŸàȘ€àȘ°à«€ àȘ•àȘ°àȘ”àȘŸ, àȘ‰àȘȘàȘ° àȘŠàȘ°à«àȘ¶àȘŸàȘ”ેàȘČàȘŸ àȘšàȘ‚àȘŹàȘ° àȘ€à«‡àȘźàȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘžàȘŸàȘ„ે àȘžàȘ°àȘ–àȘŸàȘ”ો. àȘ€à«‡àȘ“ àȘ€à«‡àȘźàȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘžàȘ„ી àȘȘàȘŁ àȘ€àȘźàȘŸàȘ°à«‹ àȘ•à«‹àȘĄ àȘžà«àȘ•ેàȘš àȘ•àȘ°à«€ àȘ¶àȘ•ે àȘ›à«‡.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°à«‹àȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ°à«‹", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal àȘȘàȘ° àȘ†àȘ”àȘšàȘŸàȘ°àȘŸ àȘ—à«‹àȘȘàȘšà«€àȘŻàȘ€àȘŸ àȘ«à«€àȘšàȘ°àȘšà«‡ àȘžàȘ•્àȘ·àȘź àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡ àȘ«à«‡àȘ°àȘ«àȘŸàȘ°àȘšàȘŸ àȘžàȘźàȘŻàȘ—àȘŸàȘłàȘŸ àȘŠàȘ°àȘźàȘżàȘŻàȘŸàȘš àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°à«‹ àȘ…àȘȘàȘĄà«‡àȘŸ àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”ી àȘ°àȘč્àȘŻàȘŸàȘ‚ àȘ›à«‡.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°à«‹àȘšà«€ àȘ–àȘŸàȘ€àȘ°à«€ àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡, àȘ€àȘźàȘŸàȘ°àȘŸ àȘžàȘ‚àȘȘàȘ°à«àȘ•àȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘžàȘŸàȘ„ે àȘ•àȘČàȘ° àȘ•àȘŸàȘ°à«àȘĄàȘšà«‡ àȘźà«‡àȘš àȘ•àȘ°à«‹. àȘœà«‹ àȘ† àȘźà«‡àȘš àȘš àȘ„àȘ€àȘŸàȘ‚ àȘčોàȘŻ, àȘ€à«‹ àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ°à«‹àȘšà«€ àȘŹà«€àȘœà«€ àȘœà«‹àȘĄà«€ àȘ…àȘœàȘźàȘŸàȘ”ી àȘœà«àȘ“. àȘ«àȘ•્àȘ€ àȘàȘ• àȘœ àȘœà«‹àȘĄà«€ àȘźà«‡àȘš àȘ•àȘ°àȘ”àȘŸàȘšà«€ àȘœàȘ°à«‚àȘ° àȘ›à«‡.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àȘźàȘŠàȘŠ àȘœà«‹àȘˆàȘ àȘ›à«‡?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àȘžàȘźàȘœàȘŸàȘˆ àȘ—àȘŻà«àȘ‚", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àȘ€àȘźà«‡ àȘ† àȘ”્àȘŻàȘ•્àȘ€àȘż àȘžàȘŸàȘ„ે àȘźà«‡àȘžà«‡àȘœàȘšà«€ àȘ†àȘȘ-àȘČે àȘ•àȘ°à«àȘŻàȘŸ àȘȘàȘ›à«€ àȘ€à«‡àȘšà«€ àȘžàȘŸàȘ„ે àȘàȘ• àȘžà«‡àȘ«à«àȘŸà«€ àȘšàȘ‚àȘŹàȘ° àȘŹàȘšàȘŸàȘ”àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”àȘ¶à«‡.", @@ -1267,10 +1359,6 @@ "messageformat": "àȘ€àȘŸàȘœà«‡àȘ€àȘ°àȘšàȘŸ àȘźà«€àȘĄàȘżàȘŻàȘŸ àȘœà«àȘ“", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} àȘžàȘŸàȘ„ે àȘ€àȘźàȘŸàȘ°àȘŸ àȘàȘšà«àȘĄ-àȘŸà«‚-àȘàȘšà«àȘĄ àȘàȘšà«àȘ•્àȘ°àȘżàȘȘ્àȘ¶àȘšàȘšà«€ àȘžà«àȘ°àȘ•્àȘ·àȘŸàȘšà«€ àȘ–àȘŸàȘ€àȘ°à«€ àȘ•àȘ°àȘ”àȘŸ, àȘ‰àȘȘàȘ° àȘŠàȘ°à«àȘ¶àȘŸàȘ”ેàȘČàȘŸ àȘšàȘ‚àȘŹàȘ° àȘ€à«‡àȘźàȘšàȘŸ àȘĄàȘżàȘ”àȘŸàȘ‡àȘž àȘžàȘŸàȘ„ે àȘžàȘ°àȘ–àȘŸàȘ”ો. àȘ€à«‡àȘ“ àȘ‰àȘȘàȘ° àȘŠàȘ°à«àȘ¶àȘŸàȘ”ેàȘČ QR àȘ•à«‹àȘĄ àȘȘàȘŁ àȘžà«àȘ•ેàȘš àȘ•àȘ°à«€ àȘ¶àȘ•ે àȘ›à«‡.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àȘ€àȘźà«‡ àȘčàȘœà«€ àȘžà«àȘ§à«€ àȘ† àȘžàȘ‚àȘȘàȘ°à«àȘ• àȘžàȘŸàȘ„ે àȘ•à«‹àȘˆ àȘźà«‡àȘžà«‡àȘœàȘšà«€ àȘ†àȘȘàȘČે àȘ•àȘ°à«€ àȘšàȘ„ી. àȘȘ્àȘ°àȘ„àȘź àȘźà«‡àȘžà«‡àȘœ àȘȘàȘ›à«€ àȘ€à«‡àȘźàȘšà«€ àȘžàȘŸàȘ„ે àȘ€àȘźàȘŸàȘ°à«‹ àȘžàȘČàȘŸàȘźàȘ€à«€ àȘšàȘ‚àȘŹàȘ° àȘ‰àȘȘàȘČàȘŹà«àȘ§ àȘ„àȘ¶à«‡." }, @@ -1334,17 +1422,17 @@ "messageformat": "àȘźàȘŸàȘčàȘżàȘ€à«€", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«‹", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àȘźà«‡àȘžà«‡àȘœ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«‹", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àȘšà«‡àȘŸ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ”ી àȘ›à«‡?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àȘźà«‡àȘžà«‡àȘœ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ”àȘŸ àȘ›à«‡?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àȘ† àȘĄàȘżàȘ”àȘŸàȘ‡àȘžàȘźàȘŸàȘ‚àȘ„ી àȘ† àȘšà«‡àȘŸàȘšà«‡ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”àȘ¶à«‡.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àȘ† àȘĄàȘżàȘ”àȘŸàȘ‡àȘžàȘźàȘŸàȘ‚àȘ„ી àȘ† àȘšà«‡àȘŸàȘźàȘŸàȘ‚àȘšàȘŸ àȘźà«‡àȘžà«‡àȘœàȘšà«‡ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”àȘ¶à«‡. àȘ€àȘźà«‡ àȘźà«‡àȘžà«‡àȘœ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«€ àȘšàȘŸàȘ–à«‹ àȘ€à«‡ àȘȘàȘ›à«€ àȘȘàȘŁ àȘ€àȘźà«‡ àȘ† àȘšà«‡àȘŸ àȘźàȘŸàȘŸà«‡ àȘ¶à«‹àȘ§ àȘ•àȘ°à«€ àȘ¶àȘ•à«‹ àȘ›à«‹.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àȘ—્àȘ°à«‚àȘȘ àȘ›à«‹àȘĄà«‹", @@ -1438,6 +1526,14 @@ "messageformat": "àȘŹàȘ‚àȘšà«‡ àȘšà«‡àȘŸ àȘźàȘŸàȘŸà«‡àȘšà«€ àȘ€àȘźàȘŸàȘ°à«€ àȘźà«‡àȘžà«‡àȘœ àȘčàȘżàȘžà«àȘŸà«àȘ°à«€ àȘ…àȘčીàȘ‚ àȘźàȘ°à«àȘœ àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ†àȘ”ી àȘ›à«‡.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber}àȘ {conversationTitle} àȘšà«‹ àȘšàȘ‚àȘŹàȘ° àȘ›à«‡. àȘ€àȘźà«‡ àȘŹàȘ‚àȘšà«‡ {sharedGroup} àȘšàȘŸ àȘžàȘ­à«àȘŻà«‹ àȘ›à«‹.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber}àȘ {conversationTitle} àȘšà«‹ àȘšàȘ‚àȘŹàȘ° àȘ›à«‡", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àȘ…àȘ”àȘ€àȘ°àȘŁ àȘ•àȘ°à«‡àȘČ àȘźà«‡àȘžà«‡àȘœàȘ„ી àȘˆàȘźà«‡àȘœàȘšà«€ àȘ„àȘ‚àȘŹàȘšà«‡àȘČ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àȘ«àȘ°à«€àȘ„ી àȘ•ૉàȘČ àȘ•àȘ°à«‹", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àȘ•ૉàȘČ àȘ¶àȘ°à«‚ àȘ•àȘ°à«‹", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àȘ•ૉàȘČàȘźàȘŸàȘ‚ àȘœà«‹àȘĄàȘŸàȘ“", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àȘ•ૉàȘČàȘšà«€ àȘžàȘŸàȘ‡àȘàȘšàȘŸ àȘ•àȘŸàȘ°àȘŁà«‡ àȘźàȘŸàȘ‡àȘ•્àȘ°à«‹àȘ«à«‹àȘš àȘźà«àȘŻà«‚àȘŸ àȘ„àȘˆ àȘ—àȘŻà«‹", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àȘ•ૉàȘČ àȘšà«‹àȘŸàȘżàȘ«àȘżàȘ•ેàȘ¶àȘš", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àȘ•ૉàȘČ àȘȘૂàȘ°à«àȘŁ àȘ›à«‡", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àȘ•à«…àȘźà«‡àȘ°àȘŸ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àȘœà«‹àȘĄàȘŸàȘ“", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àȘ¶àȘ°à«‚ àȘ•àȘ°à«‹", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àȘ•ૉàȘČàȘźàȘŸàȘ‚ àȘœàȘ—્àȘŻàȘŸ àȘšàȘ„ી", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àȘ•à«…àȘźà«‡àȘ°àȘŸ àȘ…àȘ•્àȘ·àȘź àȘ›à«‡", @@ -1621,10 +1725,6 @@ "messageformat": "àȘ•à«…àȘźà«‡àȘ°àȘŸ àȘšàȘŸàȘČુ àȘ•àȘ°à«‹", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àȘźà«àȘŻà«‚àȘŸ àȘ•àȘ°à«‹", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àȘźàȘŸàȘ‡àȘ•્àȘ°à«‹àȘ«à«‹àȘš àȘ…àȘ•્àȘ·àȘź àȘ›à«‡", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àȘźàȘŸàȘ‡àȘ• àȘ…àȘšàȘźà«àȘŻà«‚àȘŸ àȘ•àȘ°à«‹", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àȘ¶à«‡àȘ° àȘ•àȘ°à«‹", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àȘ°àȘœà«‚àȘ†àȘ€ àȘ…àȘ•્àȘ·àȘź àȘ›à«‡", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àȘȘ્àȘ°àȘžà«àȘ€à«àȘ€àȘż àȘ•àȘ°àȘ”àȘŸàȘšà«àȘ‚ àȘŹàȘ‚àȘ§ àȘ•àȘ°à«‹", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àȘ°àȘżàȘ‚àȘ—", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àȘžàȘčàȘ­àȘŸàȘ—à«€àȘ“àȘšà«‡ àȘ°àȘżàȘ‚àȘ— àȘźàȘŸàȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡ àȘ—્àȘ°à«àȘȘ àȘŹàȘčુ àȘźà«‹àȘŸà«àȘ‚ àȘ›à«‡.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àȘ°àȘżàȘ‚àȘ— àȘźàȘŸàȘ°àȘ”àȘŸàȘšà«àȘ‚ àȘžàȘ•્àȘ·àȘź àȘ•àȘ°à«‹", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àȘ°àȘżàȘ‚àȘ— àȘŹàȘ‚àȘ§ àȘ•àȘ°à«‹", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àȘ°àȘżàȘ‚àȘ— àȘšàȘŸàȘČુ àȘ•àȘ°à«‹", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àȘ”àȘ§à« àȘ”àȘżàȘ•àȘČ્àȘȘો", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àȘ€àȘźà«‡", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àȘ€àȘźàȘŸàȘ°à«‹ àȘ•à«…àȘźà«‡àȘ°àȘŸ àȘŹàȘ‚àȘ§ àȘ›à«‡", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àȘžàȘČàȘŸàȘźàȘ€à«€ àȘšàȘ‚àȘŹàȘ° àȘœà«àȘ“", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àȘźà«‡àȘžà«‡àȘœ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àȘžàȘČàȘŸàȘźàȘ€à«€ àȘšàȘ‚àȘŹàȘ° àȘœà«àȘ“", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "àȘ«à«‹àȘš àȘšàȘ‚àȘŹàȘ° àȘČàȘŸàȘ”àȘ”àȘŸàȘšà«àȘ‚ àȘšàȘżàȘ·à«àȘ«àȘł. àȘ€àȘźàȘŸàȘ°à«àȘ‚ àȘ•àȘšà«‡àȘ•્àȘ¶àȘš àȘ€àȘȘàȘŸàȘžà«‹ àȘ…àȘšà«‡ àȘ«àȘ°à«€ àȘȘ્àȘ°àȘŻàȘŸàȘž àȘ•àȘ°à«‹.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àȘ€àȘźà«‡ àȘ† àȘźà«‡àȘžà«‡àȘœ àȘźà«‹àȘ•àȘČ્àȘŻà«‹ àȘ€à«àȘŻàȘŸàȘ°àȘ„ી àȘźàȘŸàȘ€à«àȘ° 3 àȘ•àȘČàȘŸàȘ•àȘšà«€ àȘ…àȘ‚àȘŠàȘ° àȘœ àȘ«à«‡àȘ°àȘ«àȘŸàȘ°à«‹ àȘČàȘŸàȘ—ુ àȘ•àȘ°à«€ àȘ¶àȘ•àȘŸàȘŻ àȘ›à«‡.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àȘ€àȘźà«‡ àȘ† àȘźà«‡àȘžà«‡àȘœ àȘźà«‹àȘ•àȘČ્àȘŻà«‹ àȘčોàȘŻ àȘ€à«àȘŻàȘŸàȘ°àȘ„ી àȘźàȘŸàȘ€à«àȘ° 24 àȘ•àȘČàȘŸàȘ•àȘšà«€ àȘ…àȘ‚àȘŠàȘ° àȘœ àȘ«à«‡àȘ°àȘ«àȘŸàȘ°à«‹ àȘČàȘŸàȘ—ુ àȘ•àȘ°à«€ àȘ¶àȘ•àȘŸàȘŻ àȘ›à«‡.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àȘ† àȘźà«‡àȘžà«‡àȘœ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«àȘŻà«‹ àȘčàȘ€à«‹.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àȘœà«‹àȘĄàȘŸàȘŁ àȘ–à«‚àȘŹ àȘźà«‹àȘŸà«àȘ‚ àȘčોàȘ”àȘŸàȘ„ી àȘŹàȘ€àȘŸàȘ”ી àȘ¶àȘ•àȘŸàȘ€à«àȘ‚ àȘšàȘ„ી.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àȘ•ેàȘŸàȘČàȘŸàȘ• àȘœà«‹àȘĄàȘŸàȘŁà«‹ àȘȘ્àȘ°àȘŠàȘ°à«àȘ¶àȘżàȘ€ àȘš àȘ•àȘ°à«€ àȘ¶àȘ•àȘŸàȘŻ àȘ€à«‡àȘ”àȘŸ àȘŹàȘčુ àȘźà«‹àȘŸàȘŸ àȘ›à«‡.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àȘŠàȘŸàȘšàȘšà«€ àȘ”àȘżàȘ—àȘ€à«‹ àȘźà«‡àȘłàȘ”àȘ”àȘŸàȘźàȘŸàȘ‚ àȘ…àȘžàȘźàȘ°à«àȘ„", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "àȘźàȘŸàȘ€à«àȘ° Signal àȘŹà«€àȘŸàȘŸ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àȘźà«‡àȘžà«‡àȘœàȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°àȘ”àȘŸàȘšà«àȘ‚ àȘ«àȘ•્àȘ€ Signal àȘŹà«€àȘŸàȘŸ àȘ‰àȘȘàȘŻà«‹àȘ—àȘ•àȘ°à«àȘ€àȘŸàȘ“ àȘźàȘŸàȘŸà«‡ àȘœ àȘ‰àȘȘàȘČàȘŹà«àȘ§ àȘ›à«‡. àȘœà«‹ àȘ€àȘźà«‡ àȘźà«‡àȘžà«‡àȘœàȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«‹ àȘ›à«‹, àȘ€à«‹ àȘ€à«‡ àȘ«àȘ•્àȘ€ Signal àȘŹà«€àȘŸàȘŸàȘšàȘŸ àȘČેàȘŸà«‡àȘžà«àȘŸ àȘ”àȘ°à«àȘàȘš àȘȘàȘ° àȘčોàȘŻ àȘ€à«‡ àȘČોàȘ•à«‹àȘšà«‡ àȘœ àȘŠà«‡àȘ–àȘŸàȘ¶à«‡.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àȘźà«‡àȘžà«‡àȘœàȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«‹", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àȘœà«‹ àȘ€àȘźà«‡ àȘźà«‡àȘžà«‡àȘœàȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«‹ àȘ›à«‹, àȘ€à«‹ àȘ€à«‡ àȘ«àȘ•્àȘ€ SignalàȘšàȘŸ àȘČેàȘŸà«‡àȘžà«àȘŸ àȘ”àȘ°à«àȘàȘš àȘȘàȘ° àȘčોàȘŻ àȘ€à«‡ àȘČોàȘ•à«‹àȘšà«‡ àȘœ àȘŠà«‡àȘ–àȘŸàȘ¶à«‡. àȘ€à«‡àȘ“ àȘœà«‹àȘˆ àȘ¶àȘ•àȘ¶à«‡ àȘ•ે àȘ€àȘźà«‡ àȘźà«‡àȘžà«‡àȘœàȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«àȘŻà«‹ àȘ›à«‡.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àȘˆàȘšàȘ•àȘźàȘżàȘ‚àȘ— àȘ”àȘżàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ ...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àȘ†àȘ‰àȘŸàȘ—à«‹àȘ‡àȘ‚àȘ— àȘ”ૉàȘ‡àȘž àȘ•ૉàȘČ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àȘ†àȘ‰àȘŸàȘ—à«‹àȘˆàȘ‚àȘ— àȘ”àȘżàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àȘ€àȘźàȘšà«‡ àȘ•ૉàȘČ àȘ•àȘ°à«€ àȘ°àȘč્àȘŻàȘŸàȘ‚ àȘ›à«‡", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àȘ«àȘ°à«€àȘ„ી àȘ•àȘšà«‡àȘ•્àȘŸ àȘ„àȘˆ àȘ°àȘč્àȘŻà«àȘ‚ àȘ›à«‡...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} àȘ”્àȘŻàȘ•્àȘ€àȘż} other {{count,number} àȘČોàȘ•à«‹}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àȘ“àȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àȘȘૂàȘ°à«‹ àȘ•àȘ°à«‹", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àȘ›à«‹àȘĄà«‹", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àȘźàȘŸàȘ‡àȘ• àȘŹàȘ‚àȘ§", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àȘźàȘŸàȘ‡àȘ• àȘšàȘŸàȘČુ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àȘ°àȘżàȘ‚àȘ— àȘšàȘŸàȘČુ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àȘ°àȘżàȘ‚àȘ— àȘŹàȘ‚àȘ§ àȘ›à«‡", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àȘžà«‡àȘŸàȘżàȘ‚àȘ—્àȘž", @@ -3468,13 +3668,25 @@ "messageformat": "àȘȘૂàȘ°à«àȘŁàȘžà«àȘ•્àȘ°à«€àȘš àȘ•ૉàȘČ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àȘ—્àȘ°à«€àȘĄ àȘ”્àȘŻà«‚ àȘȘàȘ° àȘžà«àȘ”àȘżàȘš àȘ•àȘ°à«‹", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àȘ”્àȘŻà«‚ àȘŹàȘŠàȘČો", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àȘžà«àȘȘીàȘ•àȘ° àȘ”્àȘŻà«‚ àȘȘàȘ° àȘžà«àȘ”àȘżàȘš àȘ•àȘ°à«‹", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àȘ—્àȘ°àȘżàȘĄ àȘ”્àȘŻà«‚", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àȘžàȘŸàȘ‡àȘĄàȘŹàȘŸàȘ° àȘ”્àȘŻà«‚", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àȘžà«àȘȘીàȘ•àȘ° àȘ”્àȘŻà«‚", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àȘ”્àȘŻà«‚ àȘ…àȘȘàȘĄà«‡àȘŸ àȘ„àȘŻà«‹", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àȘ•ૉàȘČ àȘ›à«‹àȘĄà«‹", @@ -3576,6 +3788,14 @@ "messageformat": "àȘŹàȘ°àȘŸàȘŹàȘ°", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àȘźà«‡àȘžà«‡àȘœàȘźàȘŸàȘ‚ àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«€ àȘ¶àȘ•àȘ€àȘŸ àȘšàȘ„ી", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àȘ† àȘźà«‡àȘžà«‡àȘœ àȘȘàȘ° àȘźàȘŸàȘ€à«àȘ° {max,number} àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘœ àȘ•àȘ°à«€ àȘ¶àȘ•àȘŸàȘŻ àȘ›à«‡.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àȘźàȘŸàȘ« àȘ•àȘ°àȘ¶à«‹, àȘ€à«‡ sgnl: // àȘČàȘżàȘ‚àȘ• àȘšà«‹ àȘ•à«‹àȘˆ àȘ…àȘ°à«àȘ„ àȘšàȘ„ી!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àȘŻà«àȘàȘ°àȘšà«‡àȘź", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àȘ€àȘźàȘŸàȘ°àȘŸ àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘžàȘŸàȘ„ે àȘ•àȘ‚àȘˆàȘ• àȘ–à«‹àȘŸà«àȘ‚ àȘ„àȘŻà«àȘ‚ àȘ›à«‡, àȘ€à«‡ àȘčàȘ”ે àȘ€àȘźàȘŸàȘ°àȘŸ àȘàȘ•àȘŸàȘ‰àȘšà«àȘŸàȘšà«‡ àȘžà«‹àȘ‚àȘȘàȘŸàȘŻà«‡àȘČુàȘ‚ àȘšàȘ„ી.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«‹", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àȘ”àȘȘàȘ°àȘŸàȘ¶àȘ•àȘ°à«àȘ€àȘŸ àȘšàȘŸàȘź àȘŹàȘšàȘŸàȘ”ો", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR àȘ•à«‹àȘĄ àȘ…àȘ„àȘ”àȘŸ àȘČàȘżàȘ‚àȘ•", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àȘŻà«àȘàȘ°àȘšà«‡àȘźàȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘžà«‡àȘŸ àȘ•àȘ°àȘ”àȘŸàȘšà«€ àȘœàȘ°à«‚àȘ° àȘ›à«‡", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘČàȘżàȘ‚àȘ•àȘšà«‡ àȘ«àȘ°à«€àȘ„ી àȘžà«‡àȘŸ àȘ•àȘ°àȘ”àȘŸàȘšà«€ àȘœàȘ°à«‚àȘ° àȘ›à«‡", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àȘ€àȘźàȘŸàȘ°à«àȘ‚ àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘ¶à«‡àȘ° àȘ•àȘ°à«‹", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°à«‹", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àȘ†àȘź àȘ•àȘ°àȘ”àȘŸàȘ„ી àȘ€àȘźàȘŸàȘ°à«àȘ‚ àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘŠà«‚àȘ° àȘ„àȘˆ àȘœàȘ¶à«‡, àȘ…àȘšà«‡ àȘ…àȘšà«àȘŻ àȘ‰àȘȘàȘŻà«‹àȘ—àȘ•àȘ°à«àȘ€àȘŸàȘ“ àȘ€à«‡àȘšà«‡ àȘČàȘˆ àȘ¶àȘ•àȘ¶à«‡. àȘ€àȘźà«‡ àȘ–àȘ°à«‡àȘ–àȘ° àȘ†àȘź àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘ—à«‹ àȘ›à«‹?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àȘ†àȘšàȘŸàȘ„ી àȘ€àȘźàȘŸàȘ°à«àȘ‚ àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘŠà«‚àȘ° àȘ„àȘˆ àȘœàȘ¶à«‡ àȘ…àȘšà«‡ àȘ€àȘźàȘŸàȘ°à«‹ QR àȘ•à«‹àȘĄ àȘ…àȘšà«‡ àȘČàȘżàȘ‚àȘ• àȘ…àȘ•્àȘ·àȘź àȘ„àȘˆ àȘœàȘ¶à«‡. “{username}” àȘ…àȘšà«àȘŻ àȘČોàȘ•à«‹ àȘŠà«àȘ”àȘŸàȘ°àȘŸ àȘŠàȘŸàȘ”ો àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡ àȘ‰àȘȘàȘČàȘŹà«àȘ§ àȘčàȘ¶à«‡. àȘ€àȘźàȘšà«‡ àȘ–àȘŸàȘ€àȘ°à«€ àȘ›à«‡?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àȘ€àȘźà«‡ àȘčàȘ”ેàȘ„ી àȘžà«àȘŸà«‹àȘ°à«€ àȘœà«‹àȘˆ àȘ•ે àȘ¶à«‡àȘ° àȘ•àȘ°à«€ àȘ¶àȘ•àȘ¶à«‹ àȘšàȘčીàȘ‚. àȘ€àȘźà«‡ àȘ€àȘŸàȘœà«‡àȘ€àȘ°àȘźàȘŸàȘ‚ àȘ¶à«‡àȘ° àȘ•àȘ°à«‡àȘČàȘŸ àȘžà«àȘŸà«‹àȘ°à«€ àȘ…àȘȘàȘĄà«‡àȘŸ àȘȘàȘŁ àȘĄàȘżàȘČીàȘŸ àȘ„àȘˆ àȘœàȘ¶à«‡.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àȘ­àȘŸàȘ·àȘŸ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àȘ­àȘŸàȘ·àȘŸ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àȘžàȘżàȘžà«àȘŸàȘźàȘšà«€ àȘ­àȘŸàȘ·àȘŸ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àȘ¶à«‹àȘ§àȘšà«€ àȘ­àȘŸàȘ·àȘŸàȘ“", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” àȘźàȘŸàȘŸà«‡ àȘ•à«‹àȘˆ àȘȘàȘ°àȘżàȘŁàȘŸàȘź àȘšàȘ„ી", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àȘžà«‡àȘŸ àȘ•àȘ°à«‹", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àȘČàȘŸàȘ—ુ àȘ•àȘ°àȘ”àȘŸ Signal àȘ°àȘżàȘžà«àȘŸàȘŸàȘ°à«àȘŸ àȘ•àȘ°à«‹", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àȘ­àȘŸàȘ·àȘŸ àȘŹàȘŠàȘČàȘ”àȘŸ àȘźàȘŸàȘŸà«‡, àȘàȘȘàȘšà«‡ àȘ°àȘżàȘžà«àȘŸàȘŸàȘ°à«àȘŸ àȘ•àȘ°àȘ”àȘŸàȘšà«€ àȘœàȘ°à«‚àȘ° àȘ›à«‡.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àȘ°àȘżàȘžà«àȘŸàȘŸàȘ°à«àȘŸ àȘ•àȘ°à«‹", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "àȘ”àȘ°à«àȘàȘš {version} àȘźàȘŸàȘŸà«‡àȘšà«àȘ‚ àȘ…àȘȘàȘĄà«‡àȘŸ àȘ‰àȘȘàȘČàȘŹà«àȘ§ àȘ›à«‡", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àȘ€àȘźàȘŸàȘ°àȘŸ àȘžà«‡àȘŸàȘżàȘ‚àȘ—્àȘž àȘžà«‡àȘ” àȘ•àȘ°àȘ”àȘŸàȘźàȘŸàȘ‚ àȘàȘ• àȘ€à«àȘ°à«àȘŸàȘż àȘ†àȘ”ી àȘčàȘ€à«€. àȘ•ૃàȘȘàȘŸ àȘ•àȘ°à«€àȘšà«‡ àȘ«àȘ°à«€ àȘȘ્àȘ°àȘŻàȘŸàȘž àȘ•àȘ°à«‹.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àȘźà«‡àȘžà«‡àȘœ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àȘ”àȘ§à« àȘžà«àȘŸàȘŸàȘ‡àȘČ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àȘ«àȘ°à«€àȘ„ી àȘžà«‡àȘŸ àȘ•àȘ°à«‹", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àȘ„àȘˆ àȘ—àȘŻà«àȘ‚", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘČàȘżàȘ‚àȘ• àȘ°àȘ‚àȘ—, {total,number}àȘźàȘŸàȘ‚àȘ„ી {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àȘœà«‹ àȘ€àȘźà«‡ àȘ€àȘźàȘŸàȘ°à«‹ QR àȘ•à«‹àȘĄ àȘ«àȘ°à«€àȘ„ી àȘžà«‡àȘŸ àȘ•àȘ°à«‹ àȘ›à«‹, àȘ€à«‹ àȘ€àȘźàȘŸàȘ°à«‹ àȘčàȘŸàȘČàȘšà«‹ QR àȘ•à«‹àȘĄ àȘ…àȘšà«‡ àȘČàȘżàȘ‚àȘ• àȘčàȘ”ે àȘ•àȘŸàȘź àȘ•àȘ°àȘ¶à«‡ àȘšàȘčીàȘ‚.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àȘČàȘżàȘ‚àȘ• àȘ«àȘ°à«€àȘ„ી àȘžà«‡àȘŸ àȘ„àȘˆ àȘ°àȘčી àȘ›à«‡...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR àȘ•à«‹àȘĄ àȘ…àȘšà«‡ àȘČàȘżàȘ‚àȘ• àȘžà«‡àȘŸ àȘ•àȘ°à«‡àȘČ àȘšàȘ„ી. àȘ€àȘźàȘŸàȘ°à«àȘ‚ àȘšà«‡àȘŸàȘ”àȘ°à«àȘ• àȘ•àȘšà«‡àȘ•્àȘ¶àȘš àȘ€àȘȘàȘŸàȘžà«‹ àȘ…àȘšà«‡ àȘ«àȘ°à«€ àȘȘ્àȘ°àȘŻàȘŸàȘž àȘ•àȘ°à«‹.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àȘ€àȘźàȘŸàȘ°à«àȘ‚ Signal àȘŻà«àȘàȘ°àȘšà«‡àȘź àȘžà«‡àȘŸ àȘ•àȘ°à«‹", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«‡àȘČàȘŸ", + "messageformat": "àȘ«à«‡àȘ°àȘ«àȘŸàȘ° àȘ•àȘ°à«‡àȘČ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "àȘ«àȘ°à«€ àȘ„ી àȘźà«‹àȘ•àȘČો", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àȘ”àȘ§à« àȘ•્àȘ°àȘżàȘŻàȘŸàȘ“", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àȘ•ૉàȘČ્àȘž", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àȘšàȘ”ો àȘ•ૉàȘČ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àȘšàȘ”ો àȘ•ૉàȘČ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àȘ”àȘ§à« àȘ•્àȘ°àȘżàȘŻàȘŸàȘ“", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àȘ•ૉàȘČ àȘčàȘżàȘžà«àȘŸà«àȘ°à«€ àȘŠà«‚àȘ° àȘ•àȘ°à«‹", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àȘ•ૉàȘČ àȘčàȘżàȘžà«àȘŸà«àȘ°à«€ àȘŠà«‚àȘ° àȘ•àȘ°àȘ”ી àȘ›à«‡?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àȘ† àȘŹàȘ§à«€ àȘ•ૉàȘČ àȘčàȘżàȘžà«àȘŸà«àȘ°à«€ àȘ•àȘŸàȘŻàȘź àȘźàȘŸàȘŸà«‡ àȘĄàȘżàȘČીàȘŸ àȘ•àȘ°àȘ¶à«‡", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àȘŠà«‚àȘ° àȘ•àȘ°àȘ”ુàȘ‚", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àȘ•ૉàȘČ àȘčàȘżàȘžà«àȘŸà«àȘ°à«€ àȘžàȘŸàȘ« àȘ•àȘ°à«€", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àȘœà«‹àȘ”àȘŸ àȘ…àȘ„àȘ”àȘŸ àȘ•ૉàȘČ àȘ¶àȘ°à«‚ àȘ•àȘ°àȘ”àȘŸ àȘźàȘŸàȘŸà«‡ àȘ•્àȘČàȘżàȘ• àȘ•àȘ°à«‹", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àȘ¶à«‹àȘ§à«‹", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àȘźàȘżàȘžà«àȘĄ àȘ•ૉàȘČàȘ„ી àȘ«àȘżàȘČ્àȘŸàȘ° àȘ•àȘ°à«‹", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àȘŸà«‹àȘ—àȘČ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àȘ•à«‹àȘˆ àȘ€àȘŸàȘœà«‡àȘ€àȘ°àȘšàȘŸ àȘ•ૉàȘČ àȘšàȘ„ી. àȘ•à«‹àȘˆ àȘźàȘżàȘ€à«àȘ°àȘšà«‡ àȘ•ૉàȘČ àȘ•àȘ°à«€àȘšà«‡ àȘ¶àȘ°à«‚àȘ†àȘ€ àȘ•àȘ°à«‹.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” àȘźàȘŸàȘŸà«‡ àȘ•à«‹àȘˆ àȘȘàȘ°àȘżàȘŁàȘŸàȘź àȘšàȘ„ી", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àȘ‡àȘšàȘ•àȘźàȘżàȘ‚àȘ—", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àȘ†àȘ‰àȘŸàȘ—à«‹àȘ‡àȘ‚àȘ—", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àȘźàȘżàȘžà«àȘĄ àȘ•ૉàȘČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àȘ—્àȘ°à«àȘȘ àȘ•ૉàȘČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àȘ•à«‹àȘˆ àȘ€àȘŸàȘœà«‡àȘ€àȘ°àȘšà«€ àȘ”àȘŸàȘ€àȘšà«€àȘ€à«‹ àȘšàȘ„ી.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” àȘźàȘŸàȘŸà«‡ àȘ•à«‹àȘˆ àȘȘàȘ°àȘżàȘŁàȘŸàȘź àȘšàȘ„ી", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àȘ†àȘ‰àȘŸàȘ—à«‹àȘ‡àȘ‚àȘ— àȘ”ૉàȘ‡àȘž àȘ•ૉàȘČ} other {àȘ‡àȘšàȘ•àȘźàȘżàȘ‚àȘ— àȘ”ૉàȘ‡àȘž àȘ•ૉàȘČ}}} Video {{direction, select, Outgoing {àȘ†àȘ‰àȘŸàȘ—à«‹àȘˆàȘ‚àȘ— àȘ”àȘżàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ} other {àȘˆàȘšàȘ•àȘźàȘżàȘ‚àȘ— àȘ”àȘżàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ}}} Group {{direction, select, Outgoing {àȘ†àȘ‰àȘŸàȘ—à«‹àȘ‡àȘ‚àȘ— àȘ—્àȘ°à«‚àȘȘ àȘ•ૉàȘČ} other {àȘ‡àȘšàȘ•àȘźàȘżàȘ‚àȘ— àȘ—્àȘ°à«‚àȘȘ àȘ•ૉàȘČ}}} other {{direction, select, Outgoing {àȘ†àȘ‰àȘŸàȘ—à«‹àȘ‡àȘ‚àȘ— àȘ•ૉàȘČ} other {àȘ†àȘ”ી àȘ°àȘčેàȘČ àȘ•à«‹àȘČ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àȘźàȘżàȘžà«àȘĄ àȘ”ૉàȘ‡àȘž àȘ•ૉàȘČ} Video {àȘźàȘżàȘžà«àȘĄ àȘ”àȘżàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ} Group {àȘźàȘżàȘžà«àȘĄ àȘ—્àȘ°à«‚àȘȘ àȘ•ૉàȘČ} other {àȘźàȘżàȘž àȘ•ૉàȘČ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àȘ…àȘšà«àȘ€à«àȘ€àȘ°àȘżàȘ€ àȘ”ૉàȘ‡àȘž àȘ•ૉàȘČ} Video {àȘ…àȘšà«àȘ€à«àȘ€àȘ°àȘżàȘ€ àȘ”àȘżàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ} Group {àȘš àȘ‰àȘȘàȘŸàȘĄà«‡àȘČો àȘ—્àȘ°à«‚àȘȘ àȘ•ૉàȘČ} other {àȘš àȘ‰àȘȘàȘŸàȘĄà«‡àȘČો àȘ•ૉàȘČ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àȘšàȘ•àȘŸàȘ°à«‡àȘČ àȘ”ૉàȘ‡àȘž àȘ•ૉàȘČ} Video {àȘšàȘ•àȘŸàȘ°à«‡àȘČ àȘ”ીàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ} Group {àȘšàȘ•àȘŸàȘ°à«‡àȘČ àȘ—્àȘ°à«‚àȘȘ àȘ•ૉàȘČ} other {àȘšàȘ•àȘŸàȘ°à«‡àȘČ àȘ•ૉàȘČ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} àȘ…àȘšà«àȘŻ àȘŸàȘŸàȘ‡àȘȘ àȘ•àȘ°à«€ àȘ°àȘč્àȘŻàȘŸ àȘ›à«‡.} other {{count,number} àȘ…àȘšà«àȘŻà«‹ àȘŸàȘŸàȘ‡àȘȘ àȘ•àȘ°à«€ àȘ°àȘč્àȘŻàȘŸàȘ‚ àȘ›à«‡.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àȘšàȘ”ુàȘ‚ àȘ¶à«àȘ‚ àȘ›à«‡", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àȘšàȘŸàȘšàȘŸ àȘ«à«‡àȘ°àȘ«àȘŸàȘ°à«‹, àȘ­à«‚àȘČ àȘžà«àȘ§àȘŸàȘ°àȘŸ àȘ…àȘšà«‡ àȘȘ્àȘ°àȘŠàȘ°à«àȘ¶àȘšàȘźàȘŸàȘ‚ àȘ”àȘ§àȘŸàȘ°à«‹. SignalàȘšà«‹ àȘ‰àȘȘàȘŻà«‹àȘ— àȘ•àȘ°àȘ”àȘŸ àȘŹàȘŠàȘČ àȘ†àȘ­àȘŸàȘ°!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àȘ† àȘ…àȘȘàȘĄà«‡àȘŸàȘźàȘŸàȘ‚ àȘ”ોàȘ‡àȘž àȘ…àȘšà«‡ àȘ”ીàȘĄàȘżàȘŻà«‹ àȘ•ૉàȘČ àȘźàȘŸàȘŸà«‡ àȘ„ોàȘĄàȘŸ àȘžà«àȘ§àȘŸàȘ°àȘŸàȘ“ àȘ…àȘšà«‡ àȘ•ેàȘŸàȘČàȘŸàȘ• àȘšàȘŸàȘšàȘŸ àȘŠàȘžà«àȘ€àȘŸàȘ”ેàȘœà«€àȘ•àȘ°àȘŁ àȘ…àȘȘàȘĄà«‡àȘŸàȘšà«‹ àȘžàȘźàȘŸàȘ”ેàȘ¶ àȘ„àȘŸàȘŻ àȘ›à«‡ (àȘ†àȘ­àȘŸàȘ°, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "àȘčàȘ”ે àȘ€àȘźà«‡ àȘ€àȘźàȘŸàȘ°àȘŸ àȘžàȘżàȘžà«àȘŸàȘź àȘžà«‡àȘŸàȘżàȘ‚àȘ—્àȘž àȘŹàȘŠàȘČ્àȘŻàȘŸ àȘ”àȘżàȘšàȘŸ SignalàȘźàȘŸàȘ‚ àȘ€àȘźàȘŸàȘ°à«€ àȘȘàȘžàȘ‚àȘŠ àȘ•àȘ°à«‡àȘČી àȘ­àȘŸàȘ·àȘŸ àȘŹàȘŠàȘČી àȘ¶àȘ•à«‹ àȘ›à«‹ (Signal àȘžà«‡àȘŸàȘżàȘ‚àȘ—્àȘž > àȘŠà«‡àȘ–àȘŸàȘ” > àȘ­àȘŸàȘ·àȘŸ)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àȘ…àȘźà«‡ àȘ•ેàȘŸàȘČàȘŸàȘ• àȘ—્àȘ°à«‚àȘȘ àȘšà«‹àȘŸàȘżàȘ«àȘżàȘ•ેàȘ¶àȘš àȘ†àȘ‡àȘ•àȘš àȘ…àȘȘàȘĄà«‡àȘŸ àȘ•àȘ°à«àȘŻàȘŸ àȘ›à«‡." + "icu:WhatsNew__v6.39--1": { + "messageformat": "àȘ…àȘźà«‡ macOS àȘȘàȘ° àȘ•ૉàȘČ àȘČોàȘŹà«€àȘźàȘŸàȘ‚ àȘœà«‹àȘĄàȘŸàȘŻàȘŸ àȘȘàȘ›à«€ àȘ•ેàȘŸàȘČીàȘ•àȘ”àȘŸàȘ° àȘ„àȘ€àȘŸàȘ‚ àȘŸà«‚àȘ‚àȘ•àȘŸ àȘ”àȘżàȘČàȘ‚àȘŹàȘšà«‡ àȘ à«€àȘ• àȘ•àȘ°à«àȘŻà«‹ àȘ›à«‡." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àȘœà«àȘŻàȘŸàȘ°à«‡ àȘ•à«‹àȘˆ àȘ—્àȘ°à«‚àȘȘ àȘ•ૉàȘČàȘźàȘŸàȘ‚ àȘœà«‹àȘĄàȘŸàȘŻ àȘ…àȘ„àȘ”àȘŸ àȘ›à«‹àȘĄà«‡ àȘ€à«àȘŻàȘŸàȘ°à«‡ àȘ”ીàȘĄàȘżàȘŻà«‹ àȘŸàȘŸàȘ‡àȘČ્àȘž àȘźàȘŸàȘŸà«‡àȘšàȘŸ àȘŸà«àȘ°àȘŸàȘšà«àȘàȘżàȘ¶àȘš àȘàȘšàȘżàȘźà«‡àȘ¶àȘšàȘšà«‡ àȘ…àȘźà«‡ àȘ à«€àȘ• àȘ•àȘ°à«àȘŻà«àȘ‚ àȘ›à«‡." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àȘčàȘ”ે àȘ€àȘźà«‡ àȘšà«‡àȘŸ àȘžà«‡àȘŸàȘżàȘ‚àȘ—્àȘžàȘšà«‡ àȘàȘĄàȘȘàȘ„ી àȘàȘ•્àȘžà«‡àȘž àȘ•àȘ°àȘ”àȘŸ àȘ…àȘ„àȘ”àȘŸ àȘ€à«‡ àȘšà«‡àȘŸàȘźàȘŸàȘ‚àȘ„ી àȘ•à«‹àȘˆ àȘȘàȘŁ àȘš àȘœà«‹àȘŻà«‡àȘČી àȘžà«àȘŸà«‹àȘ°à«€ àȘœà«‹àȘ”àȘŸ àȘźàȘŸàȘŸà«‡ àȘšà«‡àȘŸ àȘčેàȘĄàȘ°àȘźàȘŸàȘ‚ àȘȘ્àȘ°à«‹àȘ«àȘŸàȘ‡àȘČ àȘ«à«‹àȘŸà«‹ àȘ…àȘ„àȘ”àȘŸ àȘ—્àȘ°à«‚àȘȘ àȘ…àȘ”àȘ€àȘŸàȘ° àȘȘàȘ° àȘ•્àȘČàȘżàȘ• àȘ•àȘ°à«€ àȘ¶àȘ•à«‹ àȘ›à«‹. àȘ†àȘ­àȘŸàȘ°, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/he/messages.json b/_locales/he/messages.json index 596fe2057e..a8bddc3fc7 100644 --- a/_locales/he/messages.json +++ b/_locales/he/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "کڒڙڐŚȘ ŚžŚĄŚ“ Ś ŚȘŚ•Ś Ś™Ś", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ŚŚ™ŚšŚąŚ” کڒڙڐŚȘ ŚžŚĄŚ“ Ś ŚȘŚ•Ś Ś™Ś. ŚŚ€Ś©Śš ŚœŚ”ŚąŚȘڙڧ ڐŚȘ ŚȘŚ•Ś›ŚŸ ڔکڒڙڐڔ Ś•ŚœŚ™ŚŠŚ•Śš Ś§Ś©Śš ŚąŚ Ś”ŚȘŚžŚ™Ś›Ś” کڜ Signal ڛړڙ ŚœŚąŚ–Ś•Śš ڜڀŚȘŚ•Śš ڐŚȘ Ś”Ś‘ŚąŚ™Ś”. ŚŚ ڙک ڜښ ŚŠŚ•ŚšŚš ŚžŚ™Ś“Ś™ ŚœŚ”Ś©ŚȘŚžŚ© Ś‘â€“Signal, ڙک ڜښ ŚŚ€Ś©ŚšŚ•ŚȘ ŚœŚžŚ—Ś•Ś§ ڐŚȘ ڔڠŚȘŚ•Ś Ś™Ś کڜښ Ś•ŚœŚ”Ś€ŚąŚ™Śœ ŚžŚ—Ś“Ś©.\n\nŚŚ€Ś©Śš ŚœŚ™ŚŠŚ•Śš Ś§Ś©Śš ŚąŚ Ś”ŚȘŚžŚ™Ś›Ś” Ś›ŚŚŸ: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ŚžŚ—Ś™Ś§ŚȘ Ś›Śœ ڔڠŚȘŚ•Ś Ś™Ś Ś•Ś”Ś€ŚąŚœŚ” ŚžŚ—Ś“Ś©", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ŚžŚ—Ś™Ś§ŚȘ Ś ŚȘŚ•Ś Ś™Ś Ś•Ś”Ś€ŚąŚœŚ” ŚžŚ—Ś“Ś©", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ŚœŚžŚ—Ś•Ś§ ŚœŚŠŚžŚ™ŚȘŚ•ŚȘ ڐŚȘ Ś›Śœ ڔڠŚȘŚ•Ś Ś™Ś?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Ś›Śœ Ś”Ś™ŚĄŚ˜Ś•ŚšŚ™Ś™ŚȘ Ś”Ś”Ś•Ś“ŚąŚ•ŚȘ Ś•Ś”ŚžŚ“Ś™Ś” کڜښ Ś™Ś™ŚžŚ—Ś§Ś• ŚœŚŠŚžŚ™ŚȘŚ•ŚȘ ŚžŚ”ŚžŚ›Ś©Ś™Śš ڔږڔ. ŚȘڔڙڔ ڜښ ŚŚ€Ś©ŚšŚ•ŚȘ ŚœŚ”Ś©ŚȘŚžŚ© Ś‘â€“Signal Ś‘ŚžŚ›Ś©Ś™Śš ڔږڔ ŚœŚŚ—Śš Ś§Ś™Ś©Ś•ŚšŚ• ŚžŚ—Ś“Ś©. Ś–Ś” ڜڐ Ś™ŚžŚ—Ś§ Ś ŚȘŚ•Ś Ś™Ś ŚžŚ”Ś˜ŚœŚ€Ś•ŚŸ کڜښ.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Ś”Ś’ŚšŚĄŚ” کڜ ŚžŚĄŚ“ ڔڠŚȘŚ•Ś Ś™Ś کڜښ ڜڐ ŚȘŚ•ŚŚžŚȘ ŚœŚ’ŚšŚĄŚ” Ś–Ś• کڜ Signal. ڙک ŚœŚ•Ś•Ś“Ś کڀŚȘŚ—ŚȘ ڐŚȘ Ś”Ś’ŚšŚĄŚ” ڔڗړکڔ ڑڙڕŚȘŚš کڜ Signal Ś‘ŚžŚ—Ś©Ś‘ کڜښ.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ڧڕڑڄ", @@ -300,6 +316,70 @@ "messageformat": "ŚŠ'ŚŚ˜Ś™Ś", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ŚžŚ©Ś”Ś• ڔکŚȘڑک ŚąŚ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ, ڔڕڐ Ś›Ś‘Śš ڜڐ ŚžŚ§Ś•Ś©Śš ŚœŚ—Ś©Ś‘Ś•ŚŸ کڜښ. ŚŚ€Ś©Śš ŚœŚ ŚĄŚ•ŚȘ ŚœŚ”Ś’Ś“Ś™Śš ڐڕŚȘŚ• کڕڑ ڐڕ ŚœŚ‘Ś—Ś•Śš ڐڗړ ڗړک.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ŚȘŚ™Ś§Ś•ŚŸ Ś›ŚąŚȘ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ŚžŚ©Ś”Ś• ڔکŚȘڑک ŚąŚ ڧڕړ Ś”â€“QR Ś•Ś”ŚœŚ™Ś Ś§ کڜ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ, Ś”Ś Ś›Ś‘Śš ڜڐ ŚȘŚ§Ś€Ś™Ś. ŚŚ€Ś©Śš ŚœŚ™ŚŠŚ•Śš ŚœŚ™Ś Ś§ ڗړک ŚœŚ©Ś™ŚȘŚ•ŚŁ ŚąŚ ŚŚ—ŚšŚ™Ś.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ŚȘŚ™Ś§Ś•ŚŸ Ś›ŚąŚȘ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Ś”ŚŠŚ’ŚȘ ŚœŚ©Ś•Ś Ś™Ś•ŚȘ Ś Ś™Ś•Ś•Ś˜", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ś”ŚĄŚȘŚšŚȘ ŚœŚ©Ś•Ś Ś™Ś•ŚȘ Ś Ś™Ś•Ś•Ś˜", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ŚŚ™ŚšŚąŚ” کڒڙڐڔ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} Ś”Ś•Ś“ŚąŚ•ŚȘ ڜڐ Ś Ś§ŚšŚŚ•", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ŚĄŚ™ŚžŚ•ŚŸ Ś›ŚœŚ Ś Ś§ŚšŚ", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ŚŠ'ŚŚ˜Ś™Ś", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "کڙڗڕŚȘ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ŚĄŚ˜Ś•ŚšŚ™Ś–", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Ś”Ś’Ś“ŚšŚ•ŚȘ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ŚąŚ“Ś›ŚŸ ڐŚȘ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Ś€ŚšŚ•Ś€Ś™Śœ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Ś”Ś§Ś•Ś“Ś", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ś”ŚŠ'ŚŚ˜Ś™Ś Ś”ŚŚœŚ” ŚžŚŚ•Ś—ŚĄŚ Ś™Ś Ś‘ŚŚšŚ›Ś™Ś•ŚŸ Ś•Ś™Ś•Ś€Ś™ŚąŚ• Ś‘ŚȘڙڑŚȘ Ś”Ś“Ś•ŚŚš Ś”Ś Ś›Ś ŚĄ ŚšŚ§ ŚŚ ŚžŚȘŚ§Ś‘ŚœŚ•ŚȘ Ś”Ś•Ś“ŚąŚ•ŚȘ ڗړکڕŚȘ.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ś”ŚȘŚ§Ś©Śš Ś‘Ś›Śœ ږڐŚȘ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ŚœŚ”ŚŠŚ˜ŚšŚŁ Ś‘Ś›Śœ ږڐŚȘ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Ś”ŚžŚ©Śš کڙڗڔ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ŚžŚĄŚ€ŚšŚ™ Ś‘Ś˜Ś™Ś—Ś•ŚȘ ŚžŚȘŚąŚ“Ś›Ś Ś™Ś.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ŚœŚžŚ“ ŚąŚ•Ś“", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ŚžŚĄŚ€Śš Ś”Ś‘Ś˜Ś™Ś—Ś•ŚȘ Ś”Ś§Ś•Ś“Ś", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ŚžŚĄŚ€Śš Ś”Ś‘Ś˜Ś™Ś—Ś•ŚȘ ڔڑڐ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Ś’ŚšŚĄŚȘ ŚžŚĄŚ€ŚšŚ™ Ś‘Ś˜Ś™Ś—Ś•ŚȘ, {index,number} ŚžŚȘŚ•Śš {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ŚœŚĄŚžŚŸ Ś›ŚžŚŚ•ŚžŚȘ", @@ -663,33 +747,41 @@ "messageformat": "ŚœŚ Ś§Ś•ŚȘ ŚŚ™ŚžŚ•ŚȘ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "ڛړڙ ŚœŚŚžŚȘ ڐŚȘ Ś”Ś”ŚŠŚ€Ś Ś” کڜښ ŚžŚ§ŚŠŚ” ŚœŚ§ŚŠŚ” ŚąŚ {name}, ڙک ŚœŚ”Ś©Ś•Ś•ŚȘ ڐŚȘ Ś”ŚžŚĄŚ€ŚšŚ™Ś Ś©ŚœŚžŚąŚœŚ” ŚąŚ Ś”ŚžŚ›Ś©Ś™Śš کڜ Ś”ŚŠŚ“ ڔکڠڙ. Ś’Ś Ś”ŚŠŚ“ ڔکڠڙ Ś™Ś›Ś•Śœ ŚœŚĄŚšŚ•Ś§ ڐŚȘ ڔڧڕړ کڜښ ŚąŚ Ś”ŚžŚ›Ś©Ś™Śš Ś©ŚœŚ• ڐڕ Ś©ŚœŚ”.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ŚœŚžŚ™Ś“Śą Ś Ś•ŚĄŚŁ", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "ڛړڙ ŚœŚŚžŚȘ ڐŚȘ Ś”Ś”ŚŠŚ€Ś Ś” ŚžŚ§ŚŠŚ” ŚœŚ§ŚŠŚ” کڜښ ŚąŚ {name}, ڙک ŚœŚ”ŚȘŚŚ™Ś ڐŚȘ Ś›ŚšŚ˜Ś™ŚĄŚ™Ś™ŚȘ Ś”ŚŠŚ‘Śą Ś©ŚœŚžŚąŚœŚ” ŚąŚ Ś”ŚžŚ›Ś©Ś™Śš کڜ Ś”ŚŠŚ“ ڔکڠڙ Ś•ŚœŚ”Ś©Ś•Ś•ŚȘ ڐŚȘ Ś”ŚžŚĄŚ€ŚšŚ™Ś. ŚŚ Ś”Ś ڜڐ ŚȘŚ•ŚŚžŚ™Ś, Ś€Ś©Ś•Ś˜ ŚŠŚšŚ™Śš ŚœŚ ŚĄŚ•ŚȘ ږڕڒ ŚŚ—Śš کڜ ŚžŚĄŚ€ŚšŚ™ Ś‘Ś˜Ś™Ś—Ś•ŚȘ. ŚšŚ§ ږڕڒ ڐڗړ ŚŠŚšŚ™Śš ŚœŚ”ŚȘŚŚ™Ś.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "ڛړڙ ŚœŚŚžŚȘ ڐŚȘ Ś”Ś”ŚŠŚ€Ś Ś” کڜښ ŚžŚ§ŚŠŚ” ŚœŚ§ŚŠŚ” ŚąŚ {name}, ڙک ŚœŚ”Ś©Ś•Ś•ŚȘ ڐŚȘ Ś”ŚžŚĄŚ€ŚšŚ™Ś Ś©ŚœŚžŚąŚœŚ” ŚąŚ Ś”ŚžŚ›Ś©Ś™Śš کڜ Ś”ŚŠŚ“ ڔکڠڙ. Ś’Ś Ś”ŚŠŚ“ ڔکڠڙ Ś™Ś›Ś•Śœ ŚœŚĄŚšŚ•Ś§ ڐŚȘ ڔڧڕړ کڜښ ŚąŚ Ś”ŚžŚ›Ś©Ś™Śš Ś©ŚœŚ• ڐڕ Ś©ŚœŚ”.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "کڙڠڕڙڙŚ Ś‘ŚžŚĄŚ€ŚšŚ™ Ś‘Ś˜Ś™Ś—Ś•ŚȘ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ڐڠڗڠڕ ŚžŚąŚ“Ś›Ś Ś™Ś ڐŚȘ ŚžŚĄŚ€ŚšŚ™ Ś”Ś‘Ś˜Ś™Ś—Ś•ŚȘ Ś‘ŚžŚ”ŚœŚš ŚȘڧڕڀŚȘ ŚžŚąŚ‘Śš ڛړڙ ŚœŚŚ€Ś©Śš Ś€Ś™ŚŠŚłŚšŚ™Ś ŚąŚȘŚ™Ś“Ś™Ś™Ś کڜ Ś€ŚšŚ˜Ś™Ś•ŚȘ Ś‘â€“Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ڛړڙ ŚœŚŚžŚȘ ŚžŚĄŚ€ŚšŚ™ Ś‘Ś˜Ś™Ś—Ś•ŚȘ, ڙک ŚœŚ”ŚȘŚŚ™Ś ڐŚȘ Ś›ŚšŚ˜Ś™ŚĄŚ™Ś™ŚȘ Ś”ŚŠŚ‘Śą Ś©ŚœŚžŚąŚœŚ” ŚąŚ Ś”ŚžŚ›Ś©Ś™Śš کڜ ڐڙک Ś”Ś§Ś©Śš کڜښ. ŚŚ Ś”Ś ڜڐ ŚȘŚ•ŚŚžŚ™Ś, Ś€Ś©Ś•Ś˜ ŚŠŚšŚ™Śš ŚœŚ ŚĄŚ•ŚȘ ږڕڒ ŚŚ—Śš کڜ ŚžŚĄŚ€ŚšŚ™ Ś‘Ś˜Ś™Ś—Ś•ŚȘ. ŚšŚ§ ږڕڒ ڐڗړ ŚŠŚšŚ™Śš ŚœŚ”ŚȘŚŚ™Ś.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ŚŠŚšŚ™Śš ŚąŚ–ŚšŚ”?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ڔڑڠŚȘŚ™", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ŚžŚĄŚ€Śš Ś‘Ś˜Ś™Ś—Ś•ŚȘ Ś™Ś™Ś•Ś•ŚŠŚš ŚąŚ ŚŚ“Ś Ś–Ś” ŚŚ—ŚšŚ™ Ś©ŚȘŚ—ŚœŚ™Ś€Ś• Ś‘Ś™Ś Ś™Ś›Ś Ś”Ś•Ś“ŚąŚ•ŚȘ.", @@ -1267,10 +1359,6 @@ "messageformat": "Ś”ŚŠŚ’ ŚžŚ“Ś™Ś” ŚŚ—ŚšŚ•Ś Ś”", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "ڛړڙ ŚœŚŚžŚȘ ڐŚȘ Ś”ŚŚ‘Ś˜Ś—Ś” کڜ Ś”Ś”ŚŠŚ€Ś Ś” ŚžŚ§ŚŠŚ” ŚœŚ§ŚŠŚ” کڜښ ŚąŚ {name}, ڙک ŚœŚ”Ś©Ś•Ś•ŚȘ ڐŚȘ Ś”ŚžŚĄŚ€ŚšŚ™Ś Ś©ŚœŚžŚąŚœŚ” ŚąŚ Ś”ŚžŚĄŚ€ŚšŚ™Ś Ś‘ŚžŚ›Ś©Ś™Śš کڜ Ś”ŚŠŚ“ ڔکڠڙ. Ś’Ś Ś”ŚŠŚ“ ڔکڠڙ Ś™Ś›Ś•Śœ ŚœŚĄŚšŚ•Ś§ ڐŚȘ ڧڕړ Ś”â€“QR Ś©ŚœŚžŚąŚœŚ”.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ڜڐ Ś”Ś—ŚœŚ€ŚȘ ŚąŚ“Ś™ŚŸ Ś”Ś•Ś“ŚąŚ•ŚȘ Ś›ŚœŚ©Ś”ŚŸ ŚąŚ ڐڙک Ś§Ś©Śš Ś–Ś”. ŚžŚĄŚ€Śš Ś”Ś‘Ś™Ś˜Ś—Ś•ŚŸ کڜښ ڐڙŚȘŚ• ڙڔڙڔ Ś–ŚžŚ™ŚŸ ŚœŚŚ—Śš Ś”Ś”Ś•Ś“ŚąŚ” Ś”ŚšŚŚ©Ś•Ś Ś”." }, @@ -1334,17 +1422,17 @@ "messageformat": "ŚžŚ™Ś“Śą", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ŚžŚ—Ś™Ś§Ś”", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ŚžŚ—Ś™Ś§ŚȘ Ś”Ś•Ś“ŚąŚ•ŚȘ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ŚœŚžŚ—Ś•Ś§ ŚŠ'ڐژ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ŚœŚžŚ—Ś•Ś§ Ś”Ś•Ś“ŚąŚ•ŚȘ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ŚŠ'ڐژ Ś–Ś” Ś™Ś™ŚžŚ—Ś§ ŚžŚžŚ›Ś©Ś™Śš Ś–Ś”.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Ś”Ś”Ś•Ś“ŚąŚ•ŚȘ Ś‘ŚŠŚłŚŚ˜ ڔږڔ Ś™Ś™ŚžŚ—Ś§Ś• ŚžŚžŚ›Ś©Ś™Śš Ś–Ś”. ŚąŚ“Ś™Ś™ŚŸ ŚȘڔڙڔ ڜښ ŚŚ€Ś©ŚšŚ•ŚȘ ŚœŚ—Ś€Ś© ڐŚȘ Ś”ŚŠŚłŚŚ˜ ڔږڔ ŚŚ—ŚšŚ™ ŚžŚ—Ś™Ś§ŚȘ Ś”Ś”Ś•Ś“ŚąŚ•ŚȘ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ŚąŚ–Ś™Ś‘ŚȘ Ś§Ś‘Ś•ŚŠŚ”", @@ -1438,6 +1526,14 @@ "messageformat": "Ś”Ś™ŚĄŚ˜Ś•ŚšŚ™Ś™ŚȘ Ś”Ś”Ś•Ś“ŚąŚ•ŚȘ کڜښ ŚœŚ©Ś Ś™ Ś”ŚŠ'ŚŚ˜Ś™Ś ŚžŚ•Ś–Ś’Ś” Ś›ŚŚŸ.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} Ś©Ś™Ś™Śš ڜ{conversationTitle}. Ś©Ś Ś™Ś›Ś Ś—Ś‘ŚšŚ™Ś Ś‘{sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} Ś©Ś™Ś™Śš ڜ{conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ŚȘŚžŚ•Ś Ś” ŚžŚžŚ•Ś–ŚąŚšŚȘ ŚžŚ”Ś•Ś“ŚąŚ” ŚžŚŠŚ•Ś˜Ś˜ŚȘ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ڗڙڙڒ کڕڑ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Ś”ŚȘŚ—Śœ کڙڗڔ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Ś”ŚŠŚ˜ŚšŚŁ ŚœŚ©Ś™Ś—Ś”", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Ś”ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ ŚžŚ•Ś©ŚȘڧ ŚąŚ§Ś‘ Ś’Ś•Ś“Śœ ڔکڙڗڔ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Ś”ŚȘŚšŚŚ•ŚȘ کڙڗڔ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ڔکڙڗڔ ŚžŚœŚŚ”", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ŚžŚŠŚœŚžŚ”", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Ś”ŚŠŚ˜ŚšŚ€Ś•ŚȘ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Ś”ŚȘŚ—ŚœŚ”", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ڔکڙڗڔ ŚžŚœŚŚ”", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Ś”ŚžŚŠŚœŚžŚ” ŚžŚ•Ś©Ś‘ŚȘŚȘ", @@ -1621,10 +1725,6 @@ "messageformat": "Ś”Ś€ŚąŚœ ŚžŚŠŚœŚžŚ”", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ڔکŚȘڧڔ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Ś”ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ ŚžŚ•Ś©Ś‘ŚȘ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ś‘Ś™Ś˜Ś•Śœ ڔکŚȘڧŚȘ ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Ś©ŚȘŚŁ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "کڙŚȘŚ•ŚŁ ŚžŚĄŚš ŚžŚ•Ś©Ś‘ŚȘ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Ś”Ś€ŚĄŚ§ ڜکŚȘŚŁ ŚžŚĄŚš", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ŚŠŚœŚŠŚœ", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Ś”Ś§Ś‘Ś•ŚŠŚ” Ś’Ś“Ś•ŚœŚ” ŚžŚ“Ś™ ڛړڙ ŚœŚŠŚœŚŠŚœ ڐڜ Ś”ŚžŚ©ŚȘŚȘŚ€Ś™Ś.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ŚŚ€Ś©Śš ŚŠŚœŚŠŚ•Śœ ڐڜ ŚŚ—ŚšŚ™Ś", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ڔکڑŚȘŚȘ ŚŠŚœŚŠŚ•Śœ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Ś”Ś€ŚąŚœŚȘ ŚŠŚœŚŠŚ•Śœ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ŚąŚ•Ś“ ŚŚ€Ś©ŚšŚ•Ś™Ś•ŚȘ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ڐŚȘ/Ś”", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Ś”ŚžŚŠŚœŚžŚ” کڜښ ڛڑڕڙڔ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Ś”ŚŠŚ’ŚȘ ŚžŚĄŚ€Śš Ś‘Ś˜Ś™Ś—Ś•ŚȘ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Ś©ŚœŚ™Ś—ŚȘ Ś”Ś•Ś“ŚąŚ”", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Ś”ŚŠŚ’ŚȘ ŚžŚĄŚ€Śš Ś‘Ś˜Ś™Ś—Ś•ŚȘ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Ś Ś›Ś©Śœ Ś‘ŚžŚ©Ś™Ś›ŚȘ ŚžŚĄŚ€Śš Ś˜ŚœŚ€Ś•ŚŸ. ڑړڕڧ ڐŚȘ Ś”Ś—Ś™Ś‘Ś•Śš کڜښ Ś•Ś ŚĄŚ” کڕڑ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Ś Ś™ŚȘڟ ŚœŚąŚšŚ•Śš ŚšŚ§ ŚąŚ“ 3 Ś©ŚąŚ•ŚȘ ŚžŚ–ŚžŚŸ Ś©ŚœŚ™Ś—ŚȘ Ś”Ś”Ś•Ś“ŚąŚ”.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Ś Ś™ŚȘڟ ŚœŚąŚšŚ•Śš ڐŚȘ Ś”Ś”Ś•Ś“ŚąŚ” ڔږڕ ŚšŚ§ ŚąŚ“ 24 Ś©ŚąŚ•ŚȘ ŚžŚ–ŚžŚŸ Ś”Ś©ŚœŚ™Ś—Ś” Ś©ŚœŚ”.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ś”Ś•Ś“ŚąŚ” Ś–Ś• Ś ŚžŚ—Ś§Ś”.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ڔڧڕڑڄ Ś”ŚžŚŠŚ•ŚšŚŁ Ś’Ś“Ś•Śœ ŚžŚ“Ś™ ڜŚȘŚŠŚ•Ś’Ś”.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Ś—ŚœŚ§ ŚžŚ”Ś§Ś‘ŚŠŚ™Ś Ś”ŚžŚŠŚ•ŚšŚ€Ś™Ś Ś’Ś“Ś•ŚœŚ™Ś ŚžŚ“Ś™ ڜŚȘŚŠŚ•Ś’Ś”.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ڜڐ Ś Ś™ŚȘڟ ŚœŚžŚ©Ś•Śš Ś€ŚšŚ˜Ś™ ŚȘŚšŚ•ŚžŚ”", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ŚšŚ§ ŚąŚ‘Ś•Śš Signal Ś‘Ś˜Ś", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ŚąŚšŚ™Ś›ŚȘ Ś”Ś•Ś“ŚąŚ•ŚȘ Ś–ŚžŚ™Ś Ś” ŚœŚžŚ©ŚȘŚžŚ©Ś™ Ś’ŚšŚĄŚȘ Ś”Ś‘Ś˜Ś کڜ Signal Ś‘ŚœŚ‘Ś“. ŚŚ ŚąŚ•ŚšŚ›Ś™Ś Ś”Ś•Ś“ŚąŚ”, ڔڙڐ ŚȘڔڙڔ Ś–ŚžŚ™Ś Ś” ŚšŚ§ ŚœŚŚ Ś©Ś™Ś Ś©ŚžŚ©ŚȘŚžŚ©Ś™Ś Ś‘Ś’ŚšŚĄŚȘ Ś”Ś‘Ś˜Ś Ś”ŚŚ—ŚšŚ•Ś Ś” کڜ Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ŚąŚšŚ™Ś›ŚȘ Ś”Ś•Ś“ŚąŚ”", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ŚŚ ŚąŚ•ŚšŚ›Ś™Ś Ś”Ś•Ś“ŚąŚ”, ڔڙڐ ŚȘڔڙڔ Ś–ŚžŚ™Ś Ś” ŚšŚ§ ŚœŚŚ Ś©Ś™Ś Ś©ŚžŚ©ŚȘŚžŚ©Ś™Ś Ś‘Ś’ŚšŚĄŚŚ•ŚȘ Ś”ŚŚ—ŚšŚ•Ś Ś•ŚȘ کڜ Signal. Ś”Ś Ś™Ś•Ś›ŚœŚ• ŚœŚšŚŚ•ŚȘ Ś©ŚąŚšŚ›ŚȘ Ś”Ś•Ś“ŚąŚ”.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "کڙڗŚȘ ڕڙړڐڕ Ś Ś›Ś ŚĄŚȘ
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ Ś™Ś•ŚŠŚŚȘ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "کڙڗŚȘ ڕڙړڐڕ Ś™Ś•ŚŠŚŚȘ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ŚžŚȘŚ§Ś©Śš/ŚȘ ŚŚœŚ™Śš", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ŚžŚȘŚ—Ś‘Śš ŚžŚ—Ś“Ś©â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {ڐڙک {count,number}} two {{count,number} ŚŚ Ś©Ś™Ś} many {{count,number} ŚŚ Ś©Ś™Ś} other {{count,number} ŚŚ Ś©Ś™Ś}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ŚĄŚ™Ś•Ś", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ŚąŚ–Ś™Ś‘Ś”", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ ŚžŚ•Ś©Ś‘ŚȘ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ ŚžŚ•Ś€ŚąŚœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ŚŠŚœŚŠŚ•Śœ ŚžŚ•Ś€ŚąŚœ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ŚŠŚœŚŠŚ•Śœ ŚžŚ•Ś©Ś‘ŚȘ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Ś”Ś’Ś“ŚšŚ•ŚȘ", @@ -3468,13 +3668,25 @@ "messageformat": "ŚąŚ•ŚšŚš کڙڗڔ Ś‘ŚžŚŠŚ‘ ŚžŚœŚ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Ś”Ś—ŚœŚŁ ڐڜ ŚȘŚŠŚ•Ś’ŚȘ ŚĄŚ•ŚšŚ’", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "کڙڠڕڙ ŚȘŚŠŚ•Ś’Ś”", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Ś”Ś—ŚœŚŁ ڐڜ ŚȘŚŠŚ•Ś’ŚȘ ŚšŚžŚ§Ś•Śœ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ŚȘŚŠŚ•Ś’ŚȘ Ś’ŚšŚ™Ś“", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ŚȘŚŠŚ•Ś’ŚȘ ŚĄŚšŚ’Śœ ŚŠŚ“", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ŚȘŚŠŚ•Ś’ŚȘ Ś“Ś•Ś‘Śš/ŚȘ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ŚȘŚŠŚ•Ś’Ś” ŚąŚ•Ś“Ś›Ś Ś”", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ŚąŚ–Ś•Ś‘ کڙڗڔ", @@ -3576,6 +3788,14 @@ "messageformat": "Ś‘ŚĄŚ“Śš", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ڜڐ Ś Ś™ŚȘڟ ŚœŚąŚšŚ•Śš Ś”Ś•Ś“ŚąŚ”", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ŚŚ€Ś©Śš ŚœŚ‘ŚŠŚą ŚšŚ§ {max,number} ŚąŚšŚ™Ś›Ś•ŚȘ Ś‘Ś”Ś•Ś“ŚąŚ” Ś–Ś•.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ŚĄŚœŚ™Ś—Ś”, Ś§Ś™Ś©Ś•Śš sgnl:// Ś–Ś” ڜڐ ڔڙڔ ڔڒڙڕڠڙ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Ś©Ś ŚžŚ©ŚȘŚžŚ©", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ŚžŚ©Ś”Ś• ڔکŚȘڑک ŚąŚ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ, ڔڕڐ Ś›Ś‘Śš ڜڐ ŚžŚ§Ś•Ś©Śš ŚœŚ—Ś©Ś‘Ś•ŚŸ کڜښ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ŚžŚ—Ś™Ś§ŚȘ Ś©Ś ŚžŚ©ŚȘŚžŚ©", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ŚŠŚ•Śš Ś©Ś ŚžŚ©ŚȘŚžŚ©", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "ڧڕړ QR ڐڕ ŚœŚ™Ś Ś§", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ڙک ŚœŚŚ€ŚĄ ڐŚȘ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ©", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ڙک ŚœŚŚ€ŚĄ ڐŚȘ ŚœŚ™Ś Ś§ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ©", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "کڙŚȘŚ•ŚŁ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ŚžŚ—Ś™Ś§ŚȘ Ś©Ś ŚžŚ©ŚȘŚžŚ©", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Ś–Ś” Ś™ŚĄŚ™Śš ڐŚȘ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ Ś•Ś™ŚŚ€Ś©Śš ڐڜ ŚžŚ©ŚȘŚžŚ©Ś™Ś ŚŚ—ŚšŚ™Ś ڜŚȘŚ€Ś•ŚĄ ڐڕŚȘŚ•. Ś‘Ś˜Ś•Ś— کږڔ ŚžŚ” کڑڐ ڜښ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ś–Ś” Ś™ŚĄŚ™Śš ڐŚȘ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ Ś•Ś™Ś‘Ś˜Śœ ڐŚȘ ڧڕړ Ś”â€“QR Ś•Ś”ŚœŚ™Ś Ś§ کڜښ. ŚŽ{username}ŚŽ ڙڔڙڔ Ś–ŚžŚ™ŚŸ ŚœŚŚ—ŚšŚ™Ś. ŚœŚ”ŚžŚ©Ś™Śš?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ڜڐ ŚȘڔڙڔ ڜښ ڙڕŚȘŚš ŚŚ€Ś©ŚšŚ•ŚȘ ڜکŚȘŚŁ ڐڕ ŚœŚŠŚ€Ś•ŚȘ Ś‘ŚĄŚ˜Ś•ŚšŚ™Ś–. ŚąŚ“Ś›Ś•Ś Ś™ ŚĄŚ˜Ś•ŚšŚ™ ککڙŚȘŚ€ŚȘ ŚœŚŚ—ŚšŚ•Ś Ś” Ś™Ś™ŚžŚ—Ś§Ś• Ś’Ś Ś”Ś.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "کڀڔ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "کڀڔ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "کڀŚȘ ŚžŚąŚšŚ›ŚȘ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ڗڙڀڕک کڀڕŚȘ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ŚŚ™ŚŸ ŚȘŚ•ŚŠŚŚ•ŚȘ ŚąŚ‘Ś•Śš ŚŽ{searchTerm}ŚŽ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Ś”Ś’Ś“ŚšŚ”", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ڙک ŚœŚ”Ś€ŚąŚ™Śœ ŚžŚ—Ś“Ś© ڐŚȘ Signal ڛړڙ ŚœŚ”Ś—Ś™Śœ ڐŚȘ Ś”Ś©Ś™Ś Ś•Ś™Ś™Ś", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ڛړڙ ŚœŚ”Ś—ŚœŚ™ŚŁ کڀڔ, ڙک ŚœŚ”Ś€ŚąŚ™Śœ ŚžŚ—Ś“Ś© ڐŚȘ Ś”ŚŚ€ŚœŚ™Ś§ŚŠŚ™Ś”.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ś”Ś€ŚąŚœŚ” ŚžŚ—Ś“Ś©", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ŚąŚ“Ś›Ś•ŚŸ ڐڜ Ś’ŚšŚĄŚ” {version} Ś–ŚžŚ™ŚŸ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ڔڙڙŚȘŚ” کڒڙڐڔ Ś‘Ś–ŚžŚŸ Ś©ŚžŚ™ŚšŚȘ Ś”Ś”Ś’Ś“ŚšŚ•ŚȘ کڜښ. ڐڠڐ Ś ŚĄŚ” کڕڑ.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Ś”Ś•Ś“ŚąŚ”", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ŚąŚ•Ś“ ŚĄŚ’Ś Ś•Ś Ś•ŚȘ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ŚŚ€ŚĄ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ŚĄŚ™Ś™Ś", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ŚŠŚ‘Śą ŚœŚ™Ś Ś§ کڜ Ś©Ś ŚžŚ©ŚȘŚžŚ©, {index,number} ŚžŚȘŚ•Śš {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ŚŚ™Ś€Ś•ŚĄ ڧڕړ Ś”â€“QR کڜښ Ś™Ś’ŚšŚ•Ś ŚœŚ›Śš کڧڕړ Ś”â€“QR Ś•Ś”ŚœŚ™Ś Ś§ Ś”Ś§Ś™Ś™ŚžŚ™Ś کڜښ ڜڐ Ś™Ś€ŚąŚœŚ• ڙڕŚȘŚš.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ŚžŚŚ€ŚĄŚ™Ś ŚœŚ™Ś Ś§â€Š", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "ڧڕړ QR Ś•ŚœŚ™Ś Ś§ ڜڐ ŚžŚ•Ś’Ś“ŚšŚ™Ś. ڛړڐڙ ŚœŚ‘Ś“Ś•Ś§ ڐŚȘ Ś—Ś™Ś‘Ś•Śš Ś”ŚšŚ©ŚȘ کڜښ Ś•ŚœŚ ŚĄŚ•ŚȘ کڕڑ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Ś”Ś’Ś“ŚšŚȘ Ś©Ś Ś”ŚžŚ©ŚȘŚžŚ© کڜښ Ś‘â€“Signal", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "Ś©ŚœŚ— کڕڑ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ŚąŚ•Ś“ Ś€ŚąŚ•ŚœŚ•ŚȘ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "کڙڗڕŚȘ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "کڙڗڔ ڗړکڔ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "کڙڗڔ ڗړکڔ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ŚąŚ•Ś“ Ś€ŚąŚ•ŚœŚ•ŚȘ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "ڠڙڧڕڙ Ś”Ś™ŚĄŚ˜Ś•ŚšŚ™Ś™ŚȘ کڙڗڕŚȘ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ŚœŚ Ś§Ś•ŚȘ Ś”Ś™ŚĄŚ˜Ś•ŚšŚ™Ś™ŚȘ کڙڗڕŚȘ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Ś–Ś” Ś™ŚžŚ—Ś§ ŚœŚŠŚžŚ™ŚȘŚ•ŚȘ ڐŚȘ Ś›Śœ Ś”Ś™ŚĄŚ˜Ś•ŚšŚ™Ś™ŚȘ ڔکڙڗڕŚȘ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ڠڧڔ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "کڙڗڕŚȘ ŚŚ—ŚšŚ•Ś Ś•ŚȘ Ś ŚžŚ—Ś§Ś•", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ŚŚ€Ś©Śš ŚœŚœŚ—Ś•Ś„ ڛړڙ ŚœŚ”ŚŠŚ™Ś’ ڐڕ ŚœŚ”ŚȘŚ—Ś™Śœ کڙڗڔ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ڗڙڀڕک", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ŚĄŚ™Ś Ś•ŚŸ ŚœŚ€Ś™ کڙڗڕŚȘ کڜڐ Ś ŚąŚ Ś•", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ŚąŚ•ŚšŚš", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ŚŚ™ŚŸ کڙڗڕŚȘ ŚŚ—ŚšŚ•Ś Ś•ŚȘ. ڛړڙ ŚœŚ”ŚȘŚ—Ś™Śœ, ŚŚ€Ś©Śš ŚœŚ”ŚȘŚ§Ś©Śš ŚœŚ—Ś‘Śš ڐڕ Ś—Ś‘ŚšŚ”.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ŚŚ™ŚŸ ŚȘŚ•ŚŠŚŚ•ŚȘ ŚąŚ‘Ś•Śš ŚŽ{query}ŚŽ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "کڙڗڔ Ś Ś›Ś ŚĄŚȘ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "کڙڗڔ Ś™Ś•ŚŠŚŚȘ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "کڙڗڔ کڜڐ Ś ŚąŚ ŚȘŚ”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ŚŚ™ŚŸ کڙڗڕŚȘ ڗړکڕŚȘ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ŚŚ™ŚŸ ŚȘŚ•ŚŠŚŚ•ŚȘ ŚąŚ‘Ś•Śš ŚŽ{query}ŚŽ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ Ś™Ś•ŚŠŚŚȘ} other {کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ Ś Ś›Ś ŚĄŚȘ}}} Video {{direction, select, Outgoing {کڙڗŚȘ ڕڙړڐڕ Ś™Ś•ŚŠŚŚȘ} other {کڙڗŚȘ ڕڙړڐڕ Ś Ś›Ś ŚĄŚȘ}}} Group {{direction, select, Outgoing {کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ Ś™Ś•ŚŠŚŚȘ} other {کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ Ś Ś›Ś ŚĄŚȘ}}} other {{direction, select, Outgoing {کڙڗڔ Ś™Ś•ŚŠŚŚȘ} other {کڙڗڔ Ś Ś›Ś ŚĄŚȘ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ کڜڐ Ś ŚąŚ ŚȘŚ”} Video {کڙڗŚȘ ڕڙړڐڕ کڜڐ Ś ŚąŚ ŚȘŚ”} Group {کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ کڜڐ Ś ŚąŚ ŚȘŚ”} other {کڙڗڔ کڜڐ Ś ŚąŚ ŚȘŚ”}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ کڜڐ Ś ŚąŚ ŚȘŚ”} Video {کڙڗŚȘ ڕڙړڐڕ کڜڐ Ś ŚąŚ ŚȘŚ”} Group {کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ ڜڐ Ś ŚąŚ ŚȘŚ”} other {کڙڗڔ ڜڐ Ś ŚąŚ ŚȘŚ”}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {کڙڗڔ Ś§Ś•ŚœŚ™ŚȘ ڠړڗŚȘŚ”} Video {کڙڗŚȘ ڕڙړڐڕ ڠړڗŚȘŚ”} Group {کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ ڠړڗŚȘŚ”} other {کڙڗڔ ڠړڗŚȘŚ”}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {ŚąŚ•Ś“ {count,number} ŚžŚ§ŚœŚ™Ś“/Ś”.} two {ŚąŚ•Ś“ {count,number} ŚžŚ§ŚœŚ™Ś“Ś™Ś.} many {ŚąŚ•Ś“ {count,number} ŚžŚ§ŚœŚ™Ś“Ś™Ś.} other {ŚąŚ•Ś“ {count,number} ŚžŚ§ŚœŚ™Ś“Ś™Ś.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ŚžŚ” ڗړک", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Ś”ŚȘŚŚžŚ•ŚȘ Ś§Ś˜Ś Ś•ŚȘ, ŚȘڙڧڕڠڙ Ś‘ŚŚ’Ś™Ś Ś•Ś©Ś™Ś€Ś•ŚšŚ™ Ś‘Ś™ŚŠŚ•ŚąŚ™Ś. ŚȘڕړڔ ŚąŚœ Ś”Ś©Ś™ŚžŚ•Ś© Ś‘-Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ś”ŚąŚ“Ś›Ś•ŚŸ ڔږڔ Ś›Ś•ŚœŚœ Ś›ŚžŚ” Ś©Ś™Ś€Ś•ŚšŚ™Ś ڑکڙڗڕŚȘ Ś§Ś•ŚœŚ™Ś•ŚȘ ڕکڙڗڕŚȘ ڕڙړڐڕ, Ś•Ś›ŚžŚ” ŚąŚ“Ś›Ś•Ś Ś™ ŚȘŚ™ŚąŚ•Ś“ Ś§ŚœŚ™Ś (ŚȘڕړڔ, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "ŚąŚ›Ś©Ś™Ś• ŚŚ€Ś©Śš ŚœŚ©Ś Ś•ŚȘ ڐŚȘ ڔکڀڔ Ś‘â€“Signal Ś‘ŚœŚ™ ŚœŚ©Ś Ś•ŚȘ ڐŚȘ Ś”Ś’Ś“ŚšŚ•ŚȘ Ś”ŚžŚąŚšŚ›ŚȘ (Ś”Ś’Ś“ŚšŚ•ŚȘ Signal > ŚžŚšŚŚ” > کڀڔ)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ŚąŚ“Ś›Ś Ś• Ś›ŚžŚ” ŚĄŚžŚœŚ™ Ś”ŚȘŚšŚŚ•ŚȘ ŚąŚ‘Ś•Śš ŚąŚ“Ś›Ś•Ś Ś™Ś Ś§Ś‘Ś•ŚŠŚȘŚ™Ś™Ś." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ŚȘڙڧڠڕ ŚąŚ™Ś›Ś•Ś‘ ڧڜ کڔŚȘŚšŚ—Ś© ŚœŚ€ŚąŚžŚ™Ś Ś‘â€“macOS ŚŚ—ŚšŚ™ Ś”ŚŠŚ˜ŚšŚ€Ś•ŚȘ ŚœŚ—Ś“Śš Ś”ŚžŚȘŚ Ś” کڜ کڙڗڔ." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ŚȘڙڧڠڕ ڐŚȘ ŚŚ Ś™ŚžŚŠŚ™Ś™ŚȘ Ś”ŚžŚąŚ‘Śš ŚąŚ‘Ś•Śš ŚŚšŚ™Ś—Ś™ ڕڙړڐڕ Ś›Ś©ŚžŚ™Ś©Ś”Ś• ڐڕ ŚžŚ™Ś©Ś”Ś™ ŚžŚŠŚ˜ŚšŚ€Ś™Ś ڐڕ ŚąŚ•Ś–Ś‘Ś™Ś کڙڗڔ Ś§Ś‘Ś•ŚŠŚȘŚ™ŚȘ." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ŚąŚ›Ś©Ś™Ś• ŚŚ€Ś©Śš ŚœŚœŚ—Ś•Ś„ ŚąŚœ ŚȘŚžŚ•Ś ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ڐڕ ŚŚ•Ś•Ś˜ŚŚš Ś§Ś‘Ś•ŚŠŚ” Ś‘Ś—ŚœŚ§ Ś”ŚąŚœŚ™Ś•ŚŸ کڜ Ś”ŚŠŚłŚŚ˜ ڛړڙ ŚœŚ’Ś©ŚȘ Ś‘ŚžŚ”Ś™ŚšŚ•ŚȘ ŚœŚ”Ś’Ś“ŚšŚ•ŚȘ Ś”ŚŠŚłŚŚ˜ ڐڕ ŚœŚ”ŚŠŚ™Ś’ ŚĄŚ˜Ś•ŚšŚ™Ś– کڜڐ Ś ŚŠŚ€Ś• ŚžŚ”ŚŠŚłŚŚ˜ ڔږڔ. ŚȘڕړڔ, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/hi-IN/messages.json b/_locales/hi-IN/messages.json index d4d027a8b1..30ab26da05 100644 --- a/_locales/hi-IN/messages.json +++ b/_locales/hi-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "à€Ąà„‡à€Ÿà€Ÿà€Źà„‡à€ž à€€à„à€°à„à€Ÿà€ż", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "à€•à„‹à€ˆ à€Ąà„‡à€Ÿà€Ÿà€Źà„‡à€ž à€€à„à€°à„à€Ÿà€ż à€čà„à€ˆà„€ à€†à€Ș à€€à„à€°à„à€Ÿà€ż à€•à„‹ à€•à„‰à€Șà„€ à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚ à€”à€° à€žà€źà€žà„à€Żà€Ÿ à€•à„‹ à€ à„€à€• à€•à€°à€šà„‡ à€źà„‡à€‚ à€źà€Šà€Š à€•à„‡ à€Čà€żà€ à€žà€żà€—à„à€šà€Č à€žà€Șà„‹à€°à„à€Ÿ à€žà„‡ à€žà€‚à€Șà€°à„à€• à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€ à€Żà€Šà€ż à€†à€Șà€•à„‹ à€Źà€żà€Čà„à€•à„à€Č à€…à€­à„€ à€žà€żà€—à„à€šà€Č à€•à€Ÿ à€‰à€Șà€Żà„‹à€— à€•à€°à€šà„‡ à€•à„€ à€œà€°à„‚à€°à€€ à€čà„ˆ, à€€à„‹ à€†à€Ș à€…à€Șà€šà€Ÿ à€Ąà„‡à€Ÿà€Ÿ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à€•à„‡ à€°à„€à€žà„à€Ÿà€Ÿà€°à„à€Ÿ à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€\n\nà€Żà€čà€Ÿà€‚ à€œà€Ÿà€•à€° à€žà€Șà„‹à€°à„à€Ÿ à€žà„‡ à€žà€‚à€Șà€°à„à€• à€•à€°à„‡à€‚: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "à€žà€Ÿà€°à€Ÿ à€Ąà„‡à€Ÿà€Ÿ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚ à€”à€° à€°à„€à€žà„à€Ÿà€Ÿà€°à„à€Ÿ à€•à€°à„‡à€‚", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "à€Ąà„‡à€Ÿà€Ÿ à€•à„‹ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚ à€”à€° à€°à„€à€žà„à€Ÿà€Ÿà€°à„à€Ÿ à€•à€°à„‡à€‚", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "à€žà€Ÿà€°à€Ÿ à€Ąà„‡à€Ÿà€Ÿ à€čà€źà„‡à€¶à€Ÿ à€•à„‡ à€Čà€żà€ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "à€†à€Șà€•à„€ à€žà€Ÿà€°à„€ à€žà€‚à€Šà„‡à€¶ à€čà€żà€žà„à€Ÿà„à€°à„€ à€”à€° à€źà„€à€Ąà€żà€Żà€Ÿ à€•à„‹ à€čà€źà„‡à€¶à€Ÿ à€•à„‡ à€Čà€żà€ à€‡à€ž à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€Ąà€żà€Čà„€à€Ÿ à€•à€° à€Šà€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€ à€Šà„‹à€Źà€Ÿà€°à€Ÿ à€Čà€żà€‚à€• à€•à€°à€šà„‡ à€•à„‡ à€Źà€Ÿà€Š à€čà„€ à€†à€Ș à€‡à€ž à€Ąà€żà€”à€Ÿà€‡à€ž à€Șà€° à€žà€żà€—à„à€šà€Č à€•à€Ÿ à€‰à€Șà€Żà„‹à€— à€•à€° à€Șà€Ÿà€à€‚à€—à„‡à„€ à€‡à€žà€žà„‡ à€†à€Șà€•à„‡ à€«à„‹à€š à€žà„‡ à€•à„‹à€ˆ à€­à„€ à€Ąà„‡à€Ÿà€Ÿ à€Ąà€żà€Čà„€à€Ÿ à€šà€čà„€à€‚ à€čà„‹à€—à€Ÿà„€", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "à€†à€Șà€•à„‡ à€Ąà„‡à€Ÿà€Ÿà€Źà„‡à€ž à€•à€Ÿ à€”à€°à„à€œà€Œà€š à€žà€żà€—à„à€šà€Č à€•à„‡ à€‡à€ž à€”à€°à„à€œà€Œà€š à€žà„‡ à€źà„‡à€Č à€šà€čà„€à€‚ à€–à€Ÿà€€à€Ÿ à€čà„ˆà„€ à€žà„à€šà€żà€¶à„à€šà€żà€€ à€•à€°à„‡à€‚ à€•à€ż à€†à€Ș à€…à€Șà€šà„‡ à€•à€‚à€Șà„à€Żà„‚à€Ÿà€° à€Șà€° à€žà€żà€—à„à€šà€Č à€•à€Ÿ à€žà€Źà€žà„‡ à€šà€Żà€Ÿ à€”à€°à„à€œà€Œà€š à€–à„‹à€Č à€°à€čà„‡ à€čà„ˆà€‚à„€", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&File", @@ -300,6 +316,70 @@ "messageformat": "à€šà„ˆà€Ÿ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "à€†à€Șà€•à„‡ à€Żà„‚à„›à€°à€šà„‡à€ź à€źà„‡à€‚ à€•à„à€› à€—à€Čà€€ à€čà„ˆ, à€Żà€č à€…à€Ź à€†à€Șà€•à„‡ à€…à€•à€Ÿà€‰à€‚à€Ÿ à€•à„‡ à€Čà€żà€ à€…à€žà€Ÿà€‡à€š à€šà€čà„€à€‚ à€čà„ˆà„€ à€†à€Ș à€‡à€žà„‡ à€«à€żà€° à€žà„‡ à€žà„‡à€Ÿ à€•à€°à€šà„‡ à€•à„€ à€•à„‹à€¶à€żà€¶ à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚ à€Żà€Ÿ à€à€• à€šà€Żà€Ÿ à€šà„à€š à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "à€…à€­à„€ à€ à„€à€• à€•à€°à„‡à€‚", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "à€†à€Șà€•à„‡ QR à€•à„‹à€Ą à€”à€° à€Żà„‚à„›à€°à€šà„‡à€ź à€Čà€żà€‚à€• à€źà„‡à€‚ à€•à„à€› à€—à€Ąà€Œà€Źà€Ąà€Œ à€čà„ˆ, à€Żà€č à€…à€Ź à€źà€Ÿà€šà„à€Ż à€šà€čà„€à€‚ à€čà„ˆà„€ à€Šà„‚à€žà€°à„‹à€‚ à€•à„‡ à€žà€Ÿà€„ à€žà€Ÿà€à€Ÿ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€à€• à€šà€Żà€Ÿ à€Čà€żà€‚à€• à€Źà€šà€Ÿà€à€‚à„€", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "à€…à€­à„€ à€ à„€à€• à€•à€°à„‡à€‚", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "à€Ÿà„ˆà€Ź à€Šà€żà€–à€Ÿà€à€‚", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "à€Ÿà„ˆà€Ź à€›à€żà€Șà€Ÿà€à€‚", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "à€à€• à€€à„à€°à„à€Ÿà„€ à€čà„à€ˆ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} à€…à€Șà€ à€żà€€", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "à€…à€Șà€ à€żà€€ à€šà€żà€čà„à€šà€żà€€", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "à€šà„ˆà€Ÿ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "à€•à„‰à€Č", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "à€žà„à€Ÿà„‹à€°à„€à„›", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "à€žà„‡à€Ÿà€żà€‚à€—à„à€ž", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal à€…à€Șà€Ąà„‡à€Ÿ à€•à€°à„‡à€‚", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "à€Șà„€à€›à„‡ à€œà€Ÿà€à€‚", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "à€Żà„‡ à€šà„ˆà€Ÿ à€žà€‚à€—à„à€°à€čà„€à€€ à€•à€° à€Šà€żà€ à€—à€ à€čà„ˆà€‚ à€”à€° à€‡à€šà€Źà„‰à€•à„à€ž à€źà„‡à€‚ à€€à€­à„€ à€Šà€żà€–à„‡à€‚à€—à„‡ à€…à€—à€° à€‡à€šà€źà„‡à€‚ à€•à„‹à€ˆ à€šà€Żà€Ÿ à€źà„‡à€žà„‡à€œ à€Șà„à€°à€Ÿà€Șà„à€€ à€čà„‹à€—à€Ÿà„€", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "à€«à€żà€° à€­à„€ à€•à„‰à€Č à€•à€°à„‡à€‚", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "à€«à€żà€° à€­à„€ à€œà„à„œà„‡à€‚", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "à€•à„‰à€Č à€œà€Ÿà€°à„€ à€°à€–à„‡à€‚", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€•à„‹ à€…à€Șà€Ąà„‡à€Ÿ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€°à€čà€Ÿ à€čà„ˆà„€", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "à€…à€§à€żà€• à€œà€Ÿà€šà„‡à€‚", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "à€Șà€żà€›à€Čà„€ à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "à€…à€—à€Čà„€ à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€”à€°à„à€œà€Œà€š, {index,number} / {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "à€žà€Ÿà€Ÿà€żà€Șà€żà€Ÿ à€čà„‹à€šà„‡ à€•à€Ÿ à€źà€Ÿà€°à„à€• à€•à„€à€œà„€à€Żà„‡", @@ -663,33 +747,41 @@ "messageformat": "à€œà€Ÿà€‚à€š à€•à„à€Čà€żà€Żà€° à€•à€°à„‡à€‚", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} à€•à„‡ à€žà€Ÿà€„ à€…à€Șà€šà„‡ à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€š à€•à„€ à€Șà„à€·à„à€Ÿà€ż à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€, à€Šà€Șà€° à€Šà€żà€ à€—à€ à€šà€‚à€Źà€°à„‹à€‚ à€•à„€ à€‰à€šà€•à„‡ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€€à„à€Čà€šà€Ÿ à€•à€°à„‡à€‚à„€ à€”à„‡ à€†à€Șà€•à„‡ à€•à„‹à€Ą à€•à„‹ à€…à€Șà€šà„€ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€­à„€ à€žà„à€•à„ˆà€š à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "à€…à€§à€żà€• à€œà€Ÿà€šà„‡à€‚", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} à€•à„‡ à€žà€Ÿà€„ à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€š à€žà€€à„à€Żà€Ÿà€Șà€żà€€ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€, à€Šà€Șà€° à€Šà€żà€ à€—à€ à€•à€Čà€° à€•à€Ÿà€°à„à€Ą à€•à€Ÿ à€‰à€šà€•à„€ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€źà€żà€Čà€Ÿà€š à€•à€°à„‡à€‚ à€”à€° à€šà€‚à€Źà€°à„‹à€‚ à€•à„€ à€€à„à€Čà€šà€Ÿ à€•à€°à„‡à€‚à„€ à€Żà€Šà€ż à€Żà„‡ à€źà„‡à€Č à€šà€čà„€à€‚ à€–à€Ÿà€€à„‡, à€€à„‹ à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€•à„€ à€Šà„‚à€žà€°à„€ à€œà„‹à€Ąà€Œà„€ à€†à€œà€Œà€źà€Ÿà€à€‚à„€ à€•à„‡à€”à€Č à€à€• à€œà„‹à€Ąà€Œà„€ à€•à€Ÿ à€źà€żà€Čà€Ÿà€š à„›à€°à„‚à€°à„€ à€čà„ˆà„€", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} à€•à„‡ à€žà€Ÿà€„ à€…à€Șà€šà„‡ à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€š à€•à„€ à€Șà„à€·à„à€Ÿà€ż à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€, à€Šà€Șà€° à€Šà€żà€ à€—à€ à€šà€‚à€Źà€°à„‹à€‚ à€•à„€ à€‰à€šà€•à„‡ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€€à„à€Čà€šà€Ÿ à€•à€°à„‡à€‚à„€ à€”à„‡ à€†à€Șà€•à„‡ à€•à„‹à€Ą à€•à„‹ à€…à€Șà€šà„€ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€­à„€ à€žà„à€•à„ˆà€š à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "à€žà„à€°à€•à„à€·à€Ÿ à€šà€‚à€Źà€°à„‹à€‚ à€źà„‡à€‚ à€Źà€Šà€Čà€Ÿà€”", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal à€źà„‡à€‚ à€†à€—à€Ÿà€źà„€ à€—à„‹à€Șà€šà„€à€Żà€€à€Ÿ à€«à„€à€šà€°à„à€ž à€•à„‹ à€žà€•à„à€·à€ź à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€Ÿà„à€°à€Ÿà€‚à€œà„€à€¶à€š à€…à€”à€§à€ż à€źà„‡à€‚ à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€…à€Șà€Ąà„‡à€Ÿ à€•à€żà€ à€œà€Ÿ à€°à€čà„‡ à€čà„ˆà€‚à„€", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€žà€€à„à€Żà€Ÿà€Șà€żà€€ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€, à€•à€Čà€° à€•à€Ÿà€°à„à€Ą à€•à€Ÿ à€…à€Șà€šà„‡ à€žà€‚à€Șà€°à„à€• à€•à„€ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€źà€żà€Čà€Ÿà€š à€•à€°à„‡à€‚à„€ à€Żà€Šà€ż à€Żà„‡ à€źà„‡à€Č à€šà€čà„€à€‚ à€–à€Ÿà€€à„‡, à€€à„‹ à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€•à„€ à€Šà„‚à€žà€°à„€ à€œà„‹à€Ąà€Œà„€ à€†à€œà€Œà€źà€Ÿà€à€‚à„€ à€•à„‡à€”à€Č à€à€• à€œà„‹à€Ąà€Œà„€ à€•à€Ÿ à€źà€żà€Čà€Ÿà€š à„›à€°à„‚à€°à„€ à€čà„ˆà„€", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "à€źà€Šà€Š à€šà€Ÿà€čà€żà€?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "à€žà€źà€ à€—à€Żà€Ÿ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "à€†à€Șà€•à„‡ à€Šà„à€”à€Ÿà€°à€Ÿ à€‡à€ž à€”à„à€Żà€•à„à€€à€ż à€•à„‡ à€žà€Ÿà€„ à€žà€‚à€Šà„‡à€¶à„‹à€‚ à€•à€Ÿ à€†à€Šà€Ÿà€š-à€Șà„à€°à€Šà€Ÿà€š à€•à€°à€šà„‡ à€•à„‡ à€Źà€Ÿà€Š à€à€• à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€šà€żà€°à„à€źà€żà€€ à€•à€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€", @@ -1267,10 +1359,6 @@ "messageformat": "à€čà€Ÿà€Č à€•à€Ÿ à€źà„€à€Ąà€żà€Żà€Ÿ à€Šà„‡à€–à„‡à€‚", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} à€•à„‡ à€žà€Ÿà€„ à€…à€Șà€šà„‡ à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€š à€•à„€ à€žà„à€°à€•à„à€·à€Ÿ à€•à„€ à€Șà„à€·à„à€Ÿà€ż à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€, à€Šà€Șà€° à€Šà€żà€ à€—à€ à€šà€‚à€Źà€°à„‹à€‚ à€•à„€ à€‰à€šà€•à„‡ à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€€à„à€Čà€šà€Ÿ à€•à€°à„‡à€‚à„€ à€”à„‡ à€‰à€Șà€°à„‹à€•à„à€€ QR à€•à„‹à€Ą à€•à„‹ à€­à„€ à€žà„à€•à„ˆà€š à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "à€†à€Șà€šà„‡ à€…à€­à„€ à€€à€• à€‡à€ž à€žà€‚à€Șà€°à„à€• à€•à„‡ à€žà€Ÿà€„ à€•à€żà€žà„€ à€­à„€ à€źà„‡à€žà„‡à€œ à€•à€Ÿ à€†à€Šà€Ÿà€š-à€Șà„à€°à€Šà€Ÿà€š à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€čà„ˆà„€ à€‰à€šà€•à„‡ à€žà€Ÿà€„ à€†à€Șà€•à€Ÿ à€žà„à€°à€•à„à€·à€Ÿ à€šà€‚à€Źà€° à€Șà€čà€Čà„‡ à€źà„‡à€žà„‡à€œ à€•à„‡ à€Źà€Ÿà€Š à€‰à€Șà€Čà€Źà„à€§ à€čà„‹à€—à€Ÿà„€" }, @@ -1334,17 +1422,17 @@ "messageformat": "à€œà€Ÿà€šà€•à€Ÿà€°à„€", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "à€šà„ˆà€Ÿ à€•à„‹ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à€šà€Ÿ à€čà„ˆ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "à€‡à€ž à€šà„ˆà€Ÿ à€•à„‹ à€‡à€ž à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€Ąà€żà€Čà„€à€Ÿ à€•à€° à€Šà€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "à€‡à€ž à€šà„ˆà€Ÿ à€•à„‡ à€žà€‚à€Šà„‡à€¶ à€‡à€ž à€Ąà€żà€”à€Ÿà€‡à€ž à€žà„‡ à€čà€Ÿà€Ÿ à€Šà€żà€ à€œà€Ÿà€à€‚à€—à„‡à„€ à€žà€‚à€Šà„‡à€¶ à€čà€Ÿà€Ÿà€šà„‡ à€•à„‡ à€Źà€Ÿà€Š à€­à„€ à€†à€Ș à€‡à€ž à€šà„ˆà€Ÿ à€•à„‹ à€–à„‹à€œ à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "à€žà€źà„‚à€č à€›à„‹à€Ąà€Œ à€Šà„‡à€‚", @@ -1438,6 +1526,14 @@ "messageformat": "à€Šà„‹à€šà„‹à€‚ à€šà„ˆà€Ÿ à€•à„‡ à€Čà€żà€ à€†à€Șà€•à„‡ à€žà€‚à€Šà„‡à€¶ à€‡à€€à€żà€čà€Ÿà€ž à€•à„‹ à€Żà€čà€Ÿà€‚ à€źà€°à„à€œ à€•à€° à€Šà€żà€Żà€Ÿ à€—à€Żà€Ÿ à€čà„ˆà„€", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{conversationTitle} à€•à€Ÿ à„žà„‹à€š à€šà€‚à€Źà€° {phoneNumber} à€čà„ˆà„€ à€†à€Ș à€Šà„‹à€šà„‹à€‚ à€čà„€ {sharedGroup} à€•à„‡ à€žà€Šà€žà„à€Ż à€čà„ˆà€‚à„€", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} à€•à€Ÿ à€čà„ˆ", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "à€•à„‹à€Ÿà„‡à€Ą à€źà„‡à€žà„‡à€œ à€źà„‡à€‚ à€žà„‡ à€€à€žà„à€”à„€à€° à€•à€Ÿ à€„à€‚à€Źà€šà„‡à€Č", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1582,13 +1678,9 @@ "description": "Button to call someone back" }, "icu:calling__call-again": { - "messageformat": "à€Šà„‹à€Źà€Ÿà€°à€Ÿ à€•à„‹à€Č à€•à€°à„‡à€‚", + "messageformat": "à€Šà„‹à€Źà€Ÿà€°à€Ÿ à€•à„‰à€Č à€•à€°à„‡à€‚", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "à€•à„‰à€Č à€¶à„à€°à„‚ à€•à€°à„‡à€‚", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "à€•à„‰à€Č à€žà„‡ à€œà„à€Ąà€Œà„‡à€‚", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "à€•à„‰à€Č à€źà„‡à€‚ à€Čà„‹à€—à„‹à€‚ à€•à„€ à€žà€‚à€–à„à€Żà€Ÿ à€•à„‡ à€šà€Čà€€à„‡ à€źà€Ÿà€‡à€•à„à€°à„‹à„žà„‹à€š à€źà„à€Żà„‚à€Ÿ à€•à€żà€Żà€Ÿ à€—à€Żà€Ÿ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "à€•à„‰à€Č à€šà„‹à€Ÿà€żà„žà€żà€•à„‡à€¶à€š", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "à€•à„‰à€Č à€Șà„‚à€°à„à€Ł à€čà„ˆ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "à€•à„ˆà€źà€°à€Ÿ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "à€œà„à€Ąà€Œà„‡à€‚", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "à€¶à„à€°à„‚", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "à€Șà„‚à€°à„à€Ł à€•à„‰à€Č à€•à€°à„‡à€‚", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "à€•à„ˆà€źà€°à€Ÿ à€Ąà€żà€žà„‡à€Źà€Č à€•à€żà€Żà€Ÿ à€—à€Żà€Ÿ", @@ -1621,10 +1725,6 @@ "messageformat": "à€•à„ˆà€źà€°à€Ÿ à€šà€Ÿà€Čà„‚ à€•à€°à„‡à€‚", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "à€źà„à€Żà„à€Ÿ à€•à€°à„‡à€‚", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "à€źà€Ÿà€‡à€•à„à€°à„‹à€«à„‹à€š à€Ąà€żà€žà„‡à€Źà€Č à€•à€żà€Żà€Ÿ à€—à€Żà€Ÿ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "à€źà€Ÿà€‡à€• à€•à„‹ à€…à€šà€źà„à€Żà„‚à€Ÿ à€•à€°à„‡à€‚", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "à€žà€Ÿà€à€Ÿ à€•à€°à„‡à€‚", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "à€Șà„à€°à€žà„à€€à„à€€ à€šà€żà€°à„à€Żà„‹à€—à„à€Ż à€čà„ˆ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "à€Șà„à€°à€žà„à€€à„à€€ à€•à€°à€šà€Ÿ à€Źà€‚à€Š à€•à€°à„‡à€‚", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "à€°à€żà€‚à€— à€•à€°à„‡à€‚", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "à€­à€Ÿà€— à€Čà„‡à€šà„‡ à€”à€Ÿà€Čà„‹à€‚ à€•à„‹ à€°à€żà€‚à€— à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€—à„à€°à„‚à€Ș à€Źà€čà„à€€ à€Źà€Ąà€Œà€Ÿ à€čà„ˆ.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "à€°à€żà€‚à€—à€żà€‚à€— à€•à„‹ à€à€šà„‡à€Źà€Č à€•à€°à„‡à€‚", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "à€°à€żà€‚à€—à€żà€‚à€— à€Źà€‚à€Š à€•à€°à„‡à€‚", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "à€°à€żà€‚à€—à€żà€‚à€— à€šà€Ÿà€Čà„‚ à€•à€°à„‡à€‚", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "à€…à€§à€żà€• à€”à€żà€•à€Čà„à€Ș", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "à€†à€Ș", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "à€†à€Șà€•à€Ÿ à€•à„ˆà€źà€°à€Ÿ à€Źà€‚à€Š à€čà„ˆ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€Šà„‡à€–à„‡à€‚", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "à€žà€‚à€Šà„‡à€¶", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "à€žà„à€°à€•à„à€·à€Ÿ à€žà€‚à€–à„à€Żà€Ÿ à€Šà„‡à€–à„‡à€‚", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "à„žà„‹à€š à€šà€‚à€Źà€° à€šà€čà„€à€‚ à€Čà€Ÿ à€žà€•à€Ÿà„€ à€…à€Șà€šà€Ÿ à€•à€šà„‡à€•à„à€¶à€š à€œà€Ÿà€à€šà„‡à€‚ à€”à€° à€«à€żà€° à€žà„‡ à€Șà„à€°à€Żà€Ÿà€ž à€•à€°à„‡à€‚à„€", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "à€†à€Șà€•à„‡ à€Šà„à€”à€Ÿà€°à€Ÿ à€‡à€ž à€žà€‚à€Šà„‡à€¶ à€•à„‹ à€­à„‡à€œà„‡ à€œà€Ÿà€šà„‡ à€•à„‡ 3 à€˜à€‚à€Ÿà„‡ à€•à„‡ à€­à„€à€€à€° à€čà„€ à€žà€‚à€Șà€Ÿà€Šà€š à€Čà€Ÿà€—à„‚ à€•à€żà€ à€œà€Ÿ à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "à€†à€Șà€•à„‡ à€Šà„à€”à€Ÿà€°à€Ÿ à€‡à€ž à€žà€‚à€Šà„‡à€¶ à€•à„‹ à€­à„‡à€œà„‡ à€œà€Ÿà€šà„‡ à€•à„‡ 24 à€˜à€‚à€Ÿà„‡ à€•à„‡ à€­à„€à€€à€° à€čà„€ à€žà€‚à€Șà€Ÿà€Šà€š à€Čà€Ÿà€—à„‚ à€•à€żà€ à€œà€Ÿ à€žà€•à€€à„‡ à€čà„ˆà€‚à„€", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "à€Żà€č à€źà„‡à€žà„‡à€œ à€Ąà€żà€Čà„€à€Ÿ à€•à€° à€Šà€żà€Żà€Ÿ à€—à€Żà€Ÿ à€čà„ˆà„€", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "à€…à€Ÿà„ˆà€šà€źà„‡à€‚à€Ÿ à€Șà„à€°à€Šà€°à„à€¶à€żà€€ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€čà€Ÿà€œ à€žà„‡ à€Źà€čà„à€€ à€Źà€Ąà€Œà€Ÿ à€čà„ˆà„€", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "à€•à„à€› à€…à€Ÿà„ˆà€šà€źà„‡à€‚à€Ÿ à€Șà„à€°à€Šà€°à„à€¶à€żà€€ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€čà€Ÿà€œ à€žà„‡ à€Źà€čà„à€€ à€Źà€Ąà€Œà„‡ à€čà„ˆà€‚à„€", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "à€Šà€Ÿà€š à€”à€żà€”à€°à€Ł à€Șà„à€°à€Ÿà€Șà„à€€ à€•à€°à€šà„‡ à€źà„‡à€‚ à€…à€žà€źà€°à„à€„", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "à€•à„‡à€”à€Č Signal à€Źà„€à€Ÿà€Ÿ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "à€žà€‚à€Šà„‡à€¶à„‹à€‚ à€•à€Ÿ à€žà€‚à€Șà€Ÿà€Šà€š à€•à„‡à€”à€Č Signal à€Źà„€à€Ÿà€Ÿ à€‰à€Șà€Żà„‹à€—à€•à€°à„à€€à€Ÿà€“à€‚ à€•à„‡ à€Čà€żà€ à€‰à€Șà€Čà€Źà„à€§ à€čà„ˆà„€ à€Żà€Šà€ż à€†à€Ș à€•à€żà€žà„€ à€žà€‚à€Šà„‡à€¶ à€•à„‹ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à€°à€€à„‡ à€čà„ˆà€‚, à€€à„‹ à€”à€č à€•à„‡à€”à€Č à€‰à€š à€Čà„‹à€—à„‹à€‚ à€•à„‹ à€Šà€żà€–à€Ÿà€ˆ à€Šà„‡à€—à€Ÿ à€œà„‹ Signal à€Źà„€à€Ÿà€Ÿ à€•à„‡ à€šà€”à„€à€šà€€à€ź à€žà€‚à€žà„à€•à€°à€Ł à€Șà€° à€čà„ˆà€‚à„€", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à€°à„‡à€‚", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "à€Żà€Šà€ż à€†à€Ș à€•à€żà€žà„€ à€žà€‚à€Šà„‡à€¶ à€•à„‹ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à€°à€€à„‡ à€čà„ˆà€‚, à€€à„‹ à€”à€č à€•à„‡à€”à€Č à€‰à€š à€Čà„‹à€—à„‹à€‚ à€•à„‹ à€Šà€żà€–à€Ÿà€ˆ à€Šà„‡à€—à€Ÿ à€œà„‹ Signal à€•à„‡ à€šà€”à„€à€šà€€à€ź à€žà€‚à€žà„à€•à€°à€Ł à€Șà€° à€čà„ˆà€‚à„€ à€”à„‡ à€†à€Șà€•à„‡ à€Šà„à€”à€Ÿà€°à€Ÿ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€žà€‚à€Šà„‡à€¶ à€Šà„‡à€– à€žà€•à„‡à€‚à€—à„‡à„€", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č à€† à€°à€čà„€ à€čà„ˆ...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "à€†à€‰à€Ÿà€—à„‹à€‡à€‚à€— à€”à„‰à€Żà€ž à€•à„‰à€Č", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č à€•à„€ à€œà€Ÿ à€°à€čà„€ à€čà„ˆ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} à€†à€Șà€•à„‹ à€•à„‰à€Č à€•à€° à€°à€čà„‡ à€čà„ˆà€‚", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "à€«à€żà€° à€žà„‡ à€œà„‹à€Ąà€Œ à€°à€čà„‡ à€čà„ˆà€‚...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} à€”à„à€Żà€•à„à€€à€ż} other {{count,number} à€Čà„‹à€—}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "à€‘à€Ąà€żà€Żà„‹ à€•à„‰à€Č", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "à€žà€źà€Ÿà€Șà„à€€", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "à€›à„‹à€™à„‡à€‚", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "à€źà€Ÿà€‡à€• à€Źà€‚à€Š", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "à€źà€Ÿà€‡à€• à€šà€Ÿà€Čà„‚", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "à€°à€żà€‚à€—à€żà€‚à€— à€šà€Ÿà€Čà„‚", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "à€°à€żà€‚à€—à€żà€‚à€— à€Źà€‚à€Š", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "à€žà„‡à€Ÿà€żà€‚à€—à„à€ž", @@ -3468,13 +3668,25 @@ "messageformat": "à€•à„‰à€Č à€•à„‹ à€«à„à€Čà€žà„à€•à„à€°à„€à€š à€•à€°à„‡à€‚", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "à€—à„à€°à€żà€Ą à€”à„à€Żà„‚ à€Șà€° à€žà„à€”à€żà€š à€•à€°à„‡à€‚", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "à€”à„à€Żà„ à€Źà€Šà€Čà„‡à€‚", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "à€žà„à€Șà„€à€•à€° à€”à„à€Żà„‚ à€Șà€° à€žà„à€”à€żà€š à€•à€°à„‡à€‚", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "à€—à„à€°à€żà€Ą à€”à„à€Żà„", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "à€žà€Ÿà€‡à€Ąà€Źà€Ÿà€° à€”à„à€Żà„", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "à€žà„à€Șà„€à€•à€° à€”à„à€Żà„", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "à€”à„à€Żà„ à€…à€Șà€Ąà„‡à€Ÿ à€•à€żà€Żà€Ÿ à€—à€Żà€Ÿ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "à€•à„‰à€Č à€›à„‹à€Ąà€Œà„‡à€‚", @@ -3576,6 +3788,14 @@ "messageformat": "à€ à„€à€• à€čà„ˆ", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€€à€Ÿ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "à€‡à€ž à€žà€‚à€Šà„‡à€¶ à€•à„‹ à€•à„‡à€”à€Č {max,number} à€Źà€Ÿà€° à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€€à€Ÿ à€čà„ˆà„€", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "à€•à„à€·à€źà€Ÿ à€•à€°à„‡à€‚, à€”à€č sgnl: // à€Čà€żà€‚à€• à€žà€źà€ à€źà„‡à€‚ à€šà€čà„€à€‚ à€†à€Żà€Ÿ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "à€Żà„‚à€œà€Œà€°à€šà„‡à€ź", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "à€†à€Șà€•à„‡ à€Żà„‚à„›à€°à€šà„‡à€ź à€źà„‡à€‚ à€•à„à€› à€—à€Čà€€ à€čà„ˆ, à€Żà€č à€…à€Ź à€†à€Șà€•à„‡ à€…à€•à€Ÿà€‰à€‚à€Ÿ à€•à„‡ à€Čà€żà€ à€…à€žà€Ÿà€‡à€š à€šà€čà„€à€‚ à€čà„ˆà„€", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "à€Żà„‚à„›à€° à€šà€Ÿà€ź à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "à€‰à€Șà€Żà„‹à€—à€•à€°à„à€€à€Ÿ à€šà€Ÿà€ź à€Źà€šà€Ÿà€à€", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR à€•à„‹à€Ą à€Żà€Ÿ à€Čà€żà€‚à€•", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "à€Żà„‚à„›à€°à€šà„‡à€ź à€•à„‹ à€«à€żà€° à€žà„‡ à€žà„à€„à€Ÿà€Șà€żà€€ à€•à€°à€šà„‡ à€•à„€ à€†à€”à€¶à„à€Żà€•à€€à€Ÿ à€čà„ˆ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "à€Żà„‚à„›à€°à€šà„‡à€ź à€Čà€żà€‚à€• à€•à„‹ à€«à€żà€° à€žà„‡ à€žà„à€„à€Ÿà€Șà€żà€€ à€•à€°à€šà„‡ à€•à„€ à€†à€”à€¶à„à€Żà€•à€€à€Ÿ à€čà„ˆ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "à€…à€Șà€šà€Ÿ à€Żà„‚à„›à€°à€šà„‡à€ź à€žà€Ÿà€à€Ÿ à€•à€°à„‡à€‚", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "à€Żà„‚à„›à€° à€šà€Ÿà€ź à€Ąà€żà€Čà„€à€Ÿ à€•à€°à„‡à€‚", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "à€Żà€č à€†à€Șà€•à„‡ à€Żà„‚à„›à€° à€šà€Ÿà€ź à€•à„‹ à€čà€Ÿà€Ÿ à€Šà„‡à€—à€Ÿ, à€œà€żà€žà€žà„‡ à€…à€šà„à€Ż à€Żà„‚à„›à€° à€‡à€ž à€Șà€° à€Šà€Ÿà€”à€Ÿ à€•à€° à€žà€•à„‡à€‚à€—à„‡. à€•à„à€Żà€Ÿ à€†à€Ș à€”à€Ÿà€•à€ˆ à€Żà€č à€•à€°à€šà€Ÿ à€šà€Ÿà€čà€€à„‡ à€čà„ˆà€‚?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "à€Żà€č à€†à€Șà€•à€Ÿ à€Żà„‚à„›à€°à€šà„‡à€ź à€čà€Ÿà€Ÿ à€Šà„‡à€—à€Ÿ à€”à€° à€†à€Șà€•à€Ÿ QR à€•à„‹à€Ą à€”à€° à€Čà€żà€‚à€• à€…à€•à„à€·à€ź à€•à€° à€Šà„‡à€—à€Ÿà„€ “{username}” à€…à€šà„à€Ż à€Čà„‹à€—à„‹à€‚ à€•à„‡ à€Čà€żà€ à€Šà€Ÿà€”à€Ÿ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€‰à€Șà€Čà€Źà„à€§ à€čà„‹à€—à€Ÿà„€ à€•à„à€Żà€Ÿ à€†à€Șà€•à„‹ à€Żà€•à„€à€š à€čà„ˆ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "à€…à€Ź à€†à€Ș à€žà„à€Ÿà„‹à€°à„€à„› à€š à€€à„‹ à€¶à„‡à€Żà€° à€•à€° à€Șà€Ÿà€à€‚à€—à„‡, à€š à€čà„€ à€‰à€šà„à€čà„‡à€‚ à€Šà„‡à€– à€Șà€Ÿà€à€‚à€—à„‡à„€ à€čà€Ÿà€Č à€čà„€ à€źà„‡à€‚ à€†à€Șà€•à€Ÿ à€Šà„à€”à€Ÿà€°à€Ÿ à€¶à„‡à€Żà€° à€•à€żà€ à€—à€ à€žà„à€Ÿà„‹à€°à„€ à€…à€Șà€Ąà„‡à€Ÿ à€­à„€ à€Ąà€żà€Čà„€à€Ÿ à€•à€° à€Šà€żà€ à€œà€Ÿà€à€‚à€—à„‡à„€", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "à€­à€Ÿà€·à€Ÿ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "à€­à€Ÿà€·à€Ÿ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "à€žà€żà€žà„à€Ÿà€ź à€­à€Ÿà€·à€Ÿ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "à€­à€Ÿà€·à€Ÿà€à€ à€–à„‹à€œà„‡à€‚", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” à€•à„‡ à€Čà€żà€ à€•à„‹à€ˆ à€Șà€°à€żà€Łà€Ÿà€ź à€šà€čà„€à€‚", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "à€žà„‡à€Ÿ", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "à€Čà€Ÿà€—à„‚ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ Signal à€•à„‹ à€Șà„à€šà€°à€Ÿà€°à€‚à€­ à€•à€°à„‡à€‚", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "à€­à€Ÿà€·à€Ÿ à€Źà€Šà€Čà€šà„‡ à€•à„‡ à€Čà€żà€, à€à€Ș à€•à„‹ à€Șà„à€šà€°à€Ÿà€°à€‚à€­ à€•à€°à€šà€Ÿ à€čà„‹à€—à€Ÿà„€", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "à€Șà„à€šà€ƒ à€†à€°à€‚à€­ à€•à€°à„‡à€‚", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} à€źà„‡à€‚ à€…à€Șà€Ąà„‡à€Ÿ à€•à€°à€šà„‡ à€•à€Ÿ à€”à€°à„à€¶à€š à€‰à€Șà€Čà€Źà„à€§", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "à€†à€Șà€•à„€ à€žà„‡à€Ÿà€żà€‚à€— à€žà„‡à€” à€•à€°à€€à„‡ à€”à„˜à„à€€ à€à€• à€à€°à€° à€čà„à€†. à€•à„ƒà€Șà€Żà€Ÿ à€«à€żà€° à€žà„‡ à€•à„‹à€¶à€żà€¶ à€•à€°à„‡à€‚.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "à€žà€‚à€Šà„‡à€¶", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "à€”à€° à€žà„à€Ÿà€Ÿà€‡à€Č", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "à€«à€żà€° à€žà„‡ à€žà„à€„à€Ÿà€Șà€żà€€ à€•à€°à€šà€Ÿ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "à€Șà„‚à€°à„à€Ł", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "à€Żà„‚à„›à€°à€šà„‡à€ź à€Čà€żà€‚à€• à€°à€‚à€—, {total,number} à€źà„‡à€‚ à€žà„‡ {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "à€Żà€Šà€ż à€†à€Ș à€…à€Șà€šà€Ÿ QR à€•à„‹à€Ą à€«à€żà€° à€žà„‡ à€žà„à€„à€Ÿà€Șà€żà€€ à€•à€°à€€à„‡ à€čà„ˆà€‚, à€€à„‹ à€†à€Șà€•à€Ÿ à€źà„Œà€œà„‚à€Šà€Ÿ QR à€•à„‹à€Ą à€”à€° à€Čà€żà€‚à€• à€…à€Ź à€•à€Ÿà€ź à€šà€čà„€à€‚ à€•à€°à„‡à€—à€Ÿà„€", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "à€Čà€żà€‚à€• à€«à€żà€° à€žà„‡ à€žà„à€„à€Ÿà€Șà€żà€€ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€°à€čà€Ÿ à€čà„ˆ...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR à€•à„‹à€Ą à€”à€° à€Čà€żà€‚à€• à€žà„‡à€Ÿ à€šà€čà„€à€‚ à€čà„ˆà„€ à€…à€Șà€šà„‡ à€šà„‡à€Ÿà€”à€°à„à€• à€•à€šà„‡à€•à„à€¶à€š à€•à„€ à€œà€Ÿà€‚à€š à€•à€°à€•à„‡ à€Șà„à€šà€ƒ à€Șà„à€°à€Żà€Ÿà€ž à€•à€°à„‡à€‚à„€", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "à€…à€Șà€šà€Ÿ Signal à€‰à€Șà€Żà„‹à€—à€•à€°à„à€€à€Ÿ à€šà€Ÿà€ź à€žà„‡à€Ÿà€…à€Ș à€•à€°à„‡à€‚", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "à€«à€żà€° à€žà„‡ à€­à„‡à€œà„‡à€‚", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "à€…à€§à€żà€• à€•à€šà„‡à€•à„à€¶à€š", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "à€•à„‰à€Č", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "à€šà€ˆ à€•à„‰à€Č", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "à€šà€ˆ à€•à„‰à€Č", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "à€…à€§à€żà€• à€•à€šà„‡à€•à„à€¶à€š", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà€Ÿà€« à€•à€°à„‡à€‚", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà€Ÿà€« à€•à€°à„‡à€‚?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "à€‡à€žà€žà„‡ à€žà€­à„€ à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà„à€„à€Ÿà€Żà„€ à€°à„‚à€Ș à€žà„‡ à€čà€Ÿ à€œà€Ÿà€à€—à€Ÿ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "à€čà€Ÿà€Ÿà€à€", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà€Ÿà€« à€•à€żà€Żà€Ÿ à€—à€Żà€Ÿ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "à€•à„‰à€Č à€Šà„‡à€–à€šà„‡ à€Żà€Ÿ à€¶à„à€°à„‚ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€•à„à€Čà€żà€• à€•à€°à„‡à€‚", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "à€žà€°à„à€š", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "à€źà€żà€žà„à€Ą à€Šà„à€”à€Ÿà€°à€Ÿ à„žà€żà€Čà„à€Ÿà€° à€•à€°à„‡à€‚", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "à€Ÿà„‰à€—à€Č à€•à€°à„‡à€‚", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "à€•à„‹à€ˆ à€šà€”à„€à€šà€€à€ź à€•à„‰à€Č à€šà€čà„€à€‚à„€ à€•à€żà€žà„€ à€Šà„‹à€žà„à€€ à€•à„‹ à€•à„‰à€Č à€•à€°à€•à„‡ à€¶à„à€°à„‚ à€•à€°à„‡à€‚à„€", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” à€•à„‡ à€Čà€żà€ à€•à„‹à€ˆ à€Șà€°à€żà€Łà€Ÿà€ź à€šà€čà„€à€‚", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "à€‡à€šà€•à€źà€żà€‚à€—", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "à€†à€‰à€Ÿà€—à„‹à€‡à€‚à€—", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "à€źà€żà€žà„à€Ą", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "à€—à„à€°à„à€Ș à€•à„‰à€Č", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "à€•à„‹à€ˆ à€čà€Ÿà€Čà€żà€Żà€Ÿ à€Źà€Ÿà€€à€šà„€à€€ à€šà€čà„€à€‚à„€", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” à€•à„‡ à€Čà€żà€ à€•à„‹à€ˆ à€Șà€°à€żà€Łà€Ÿà€ź à€šà€čà„€à€‚", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {à€†à€‰à€Ÿà€—à„‹à€‡à€‚à€— à€”à„‰à€Żà€ž à€•à„‰à€Č} other {à€‡à€šà€•à€źà€żà€‚à€— à€”à„‰à€Żà€ž à€•à„‰à€Č}}} Video {{direction, select, Outgoing {à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č à€•à„€ à€œà€Ÿ à€°à€čà„€ à€čà„ˆ} other {à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č à€† à€°à€čà„€ à€čà„ˆ}}} Group {{direction, select, Outgoing {à€†à€‰à€Ÿà€—à„‹à€‡à€‚à€— à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€‡à€šà€•à€źà€żà€‚à€— à€—à„à€°à„à€Ș à€•à„‰à€Č}}} other {{direction, select, Outgoing {à€œà€Ÿà€šà„‡ à€”à€Ÿà€Čà„€ à€•à„‰à€Č} other {à€†à€šà„‡ à€”à€Ÿà€Čà„€ à€•à„‰à€Č}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {à€›à„‚à€Ÿà„€ à€čà„à€ˆ à€”à„‰à€Żà€ž à€•à„‰à€Č} Video {à€źà€żà€ž à€čà„à€ˆ à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č} Group {à€źà€żà€žà„à€Ą à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€źà€żà€ž à€•à„‰à€Č}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {à€…à€šà„à€€à„à€€à€°à€żà€€ à€”à„‰à€Żà€ž à€•à„‰à€Č} Video {à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č à€œà„‹ à€‰à€ à€Ÿà€ˆ à€šà€čà„€à€‚ à€—à€ˆ} Group {à€…à€šà„à€€à„à€€à€°à€żà€€ à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€…à€šà„à€€à„à€€à€°à€żà€€ à€•à„‰à€Č}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {à€…à€žà„à€”à„€à€•à„ƒà€€ à€”à„‰à€Żà€ž à€•à„‰à€Č} Video {à€…à€žà„à€”à„€à€•à„ƒà€€ à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č} Group {à€…à€žà„à€”à„€à€•à„ƒà€€ à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€…à€žà„à€”à„€à€•à„ƒà€€ à€•à„‰à€Č}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} à€…à€šà„à€Ż à€Ÿà€Ÿà€‡à€Ș à€•à€° à€°à€čà€Ÿ/à€°à€čà„€ à€čà„ˆà„€} other {{count,number} à€…à€šà„à€Ż à€Ÿà€Ÿà€‡à€Ș à€•à€° à€°à€čà„‡/à€°à€čà„€ à€čà„ˆà€‚à„€}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "à€šà€Żà€Ÿ à€•à„à€Żà€Ÿ à€čà„ˆ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "à€›à„‹à€Ÿà„‡-à€›à„‹à€Ÿà„‡ à€Ÿà„à€”à„€à€•, à€Źà€— à„žà€żà€•à„à€ž, à€”à€° à€Șà„à€°à€Šà€°à„à€¶à€š à€źà„‡à€‚ à€žà„à€§à€Ÿà€°à„€ Signal à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€§à€šà„à€Żà€”à€Ÿà€Šà„€", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "à€‡à€ž à€…à€Șà€Ąà„‡à€Ÿ à€źà„‡à€‚ à€”à„‰à€Żà€ž à€”à€° à€”à„€à€Ąà€żà€Żà„‹ à€•à„‰à€Č à€•à„‡ à€Čà€żà€ à€•à„à€› à€žà„à€§à€Ÿà€° à€”à€° à€•à„à€› à€›à„‹à€Ÿà„‡ à€Ąà„‰à€•à„à€Żà„‚à€źà„‡à€‚à€Ÿà„‡à€¶à€š à€…à€Șà€Ąà„‡à€Ÿ à€¶à€Ÿà€źà€żà€Č à€čà„ˆà€‚ (à€§à€šà„à€Żà€”à€Ÿà€Š, {linkToGithub}!)à„€" + "icu:WhatsNew__v6.39--0": { + "messageformat": "à€…à€Ź à€†à€Ș à€…à€Șà€šà„€ à€žà€żà€žà„à€Ÿà€ź à€žà„‡à€Ÿà€żà€‚à€—à„à€ž (Signal à€žà„‡à€Ÿà€żà€‚à€—à„à€ž > à€Šà€żà€–à€Ÿà€”à€Ÿ > à€­à€Ÿà€·à€Ÿ) à€•à„‹ à€Źà€Šà€Čà„‡ à€Źà€żà€šà€Ÿ Signal à€źà„‡à€‚ à€…à€Șà€šà„€ à€šà€Żà€šà€żà€€ à€­à€Ÿà€·à€Ÿ à€Źà€Šà€Č à€žà€•à€€à„‡ à€čà„ˆà€‚à„€" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "à€čà€źà€šà„‡ à€žà€źà„‚à€č à€…à€Șà€Ąà„‡à€Ÿ à€•à„‡ à€Čà€żà€ à€Šà€żà€–à€Ÿà€ˆ à€Šà„‡à€šà„‡ à€”à€Ÿà€Čà„‡ à€šà„‹à€Ÿà€żà„žà€żà€•à„‡à€¶à€š à€†à€‡à€•à€š à€•à„‹ à€žà€‚à€¶à„‹à€§à€żà€€ à€•à€żà€Żà€Ÿ à€čà„ˆ, à€œà„ˆà€žà„‡ à€•à€ż à€œà€Ź à€•à„‹à€ˆ à€šà€Żà€Ÿ à€”à„à€Żà€•à„à€€à€ż à€žà€źà„‚à€č à€źà„‡à€‚ à€¶à€Ÿà€źà€żà€Č à€čà„‹à€€à€Ÿ à€čà„ˆà„€ à€Żà„‡ à€†à€‡à€•à€š à€žà„à€Șà€Ÿà€ à„à€Żà€€à€Ÿ à€•à„‹ à€Źà„‡à€čà€€à€° à€Źà€šà€Ÿà€šà„‡ à€źà„‡à€‚ à€źà€Šà€Š à€•à€°à€€à„‡ à€čà„ˆà€‚, à€–à€Ÿà€žà€•à€° à€Żà€Šà€ż à€†à€Ș à€Ąà€Ÿà€°à„à€• à€„à„€à€ź à€•à„‡ à€…à€‚à€§à„‡à€°à„‡ à€źà„‡à€‚ à€°à€čà€€à„‡ à€čà„ˆà€‚à„€ à€Șà€żà€›à€Čà„‡ à€†à€‡à€•à€š à€Ąà€Ÿà€°à„à€• à€źà„‹à€Ą à€•à„‡ à€‡à€€à€šà„‡ à€…à€šà„à€•à„‚à€Č à€šà€čà„€à€‚ à€„à„‡à„€ à€šà€ à€†à€‡à€•à€š à€Źà€żà€Čà„à€•à„à€Č à€…à€Čà€— à€čà„ˆà€‚à„€" + "icu:WhatsNew__v6.39--1": { + "messageformat": "à€čà€źà€šà„‡ macOS à€Ąà€żà€”à€Ÿà€‡à€žà„‡à€ž à€Șà€° à€•à„‰à€Č à€Čà„‰à€Źà„€ à€źà„‡à€‚ à€¶à€Ÿà€źà€żà€Č à€čà„‹à€šà„‡ à€•à„‡ à€Šà„Œà€°à€Ÿà€š à€•à€­à„€-à€•à€­à„€ à€čà„‹à€šà„‡ à€”à€Ÿà€Čà„€ à€Šà„‡à€°à„€ à€•à„‹ à€ à„€à€• à€•à€° à€Šà€żà€Żà€Ÿ à€čà„ˆ, à€œà€żà€žà€•à€Ÿ à€źà€€à€Čà€Ź à€čà„ˆ à€•à€ż à€…à€Ź à€źà„€à€Ÿà€żà€‚à€— à€źà„‡à€‚ à€Šà„‡à€°à„€ à€žà„‡ à€†à€šà„‡ à€•à€Ÿ à€Źà€čà€Ÿà€šà€Ÿ à€šà€čà„€à€‚ à€šà€Čà„‡à€—à€Ÿà„€" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "à€œà€Ź à€•à„‹à€ˆ à€—à„à€°à„à€Ș à€•à„‰à€Č à€źà„‡à€‚ à€¶à€Ÿà€źà€żà€Č à€čà„‹à€€à€Ÿ à€čà„ˆ à€Żà€Ÿ à€›à„‹à€Ąà€Œà€€à€Ÿ à€čà„ˆ à€€à„‹ à€čà€źà€šà„‡ à€”à„€à€Ąà€żà€Żà„‹ à€Ÿà€Ÿà€‡à€Čà„à€ž à€•à„‡ à€Čà€żà€ à€Ÿà„à€°à€Ÿà€‚à€œà€Œà€żà€¶à€š à€à€šà„€à€źà„‡à€¶à€š à€€à€Ż à€•à€żà€Żà€Ÿ à€čà„ˆà„€ à€œà€Ź à€†à€Ș à€•à€żà€žà„€ à€źà€żà€€à„à€° à€•à€Ÿ à€šà„‡à€čà€°à€Ÿ à€žà€Ÿà€źà€šà„‡ à€†à€€à„‡ à€Šà„‡à€–à€€à„‡ à€čà„ˆà€‚, à€€à„‹ à€Żà€č à€à€• à€žà€Ÿà€źà€Ÿà€œà€żà€• à€†à€‚à€Šà„‹à€Čà€š à€čà„ˆà„€" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "à€…à€Ź à€†à€Ș à€šà„ˆà€Ÿ à€žà„‡à€Ÿà€żà€‚à€—à„à€ž à€€à€• à€€à„à€°à€‚à€€ à€Șà€čà„à€‚à€šà€šà„‡ à€Żà€Ÿ à€‰à€ž à€šà„ˆà€Ÿ à€žà„‡ à€•à€żà€žà„€ à€­à„€ à€…à€šà€Šà„‡à€–à„€ à€žà„à€Ÿà„‹à€°à„€à„› à€•à„‹ à€Šà„‡à€–à€šà„‡ à€•à„‡ à€Čà€żà€ à€šà„ˆà€Ÿ à€čà„‡à€Ąà€° à€źà„‡à€‚ à€Șà„à€°à„‹à€«à€Ÿà€‡à€Č à€«à„‹à€Ÿà„‹ à€Żà€Ÿ à€—à„à€°à„à€Ș à€…à€”à€€à€Ÿà€° à€Șà€° à€•à„à€Čà€żà€• à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€ à€§à€šà„à€Żà€”à€Ÿà€Š, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/hr-HR/messages.json b/_locales/hr-HR/messages.json index 4771a66227..ef72503be9 100644 --- a/_locales/hr-HR/messages.json +++ b/_locales/hr-HR/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "PogreĆĄka baze podataka", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "DoĆĄlo je do pogreĆĄke u bazi podataka. Kopirajte pogreĆĄku i kontaktirajte korisničku podrĆĄku Signala kako bi vam pomogli rijeĆĄiti problem. Ako vam je odmah potreban pristup Signalu, moĆŸete izbrisati svoje podatke i ponovno ga pokrenuti.\n\nKontaktirajte korisničku podrĆĄku putem ove poveznice: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "IzbriĆĄi sve podatke i ponovno pokreni", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "IzbriĆĄi podatke i ponovno pokreni", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Ćœelite li trajno izbrisati sve podatke?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "VaĆĄa čitava povijest poruka i svi medijski zapisi bit će trajno izbrisani s ovog uređaja. Moći ćete koristiti Signal na ovom uređaju nakon ponovnog povezivanja. Time se neće izbrisati podaci s vaĆĄeg mobilnog uređaja.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Verzija vaĆĄe baze podataka ne odgovara ovoj verziji Signala. Provjerite jeste li pokrenuli najnoviju verziju Signala na svom računalu.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Datoteka", @@ -300,6 +316,70 @@ "messageformat": "Razgovori", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "DoĆĄlo je do pogreĆĄke s vaĆĄim korisničkim imenom – nije viĆĄe povezano s vaĆĄim računom. PokuĆĄajte ga ponovno postaviti ili odabrati novo.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Ispravi odmah", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "DoĆĄlo je do pogreĆĄke – vaĆĄ QR kĂŽd i poveznica s korisničkim imenom viĆĄe nisu vaĆŸeći. Stvorite novu poveznicu i podijelite je s prijateljima.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Ispravi odmah", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "PrikaĆŸi kartice", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Sakrij kartice", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "DoĆĄlo je do pogreĆĄke", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "Nepročitano: {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Označeno kao nepročitano", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Razgovori", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Pozivi", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Priče", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Postavke", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "AĆŸuriraj Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Natrag", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ovi razgovori su arhivirani i prikazuju se na početnoj stranici samo ako primite nove poruke.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Svejedno nazovi", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Svejedno se pridruĆŸi", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Nastavi poziv", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "AĆŸuriramo sigurnosne brojeve.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Saznajte viĆĄe", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Prethodni sigurnosni broj", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Sljedeći sigurnosni broj", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Verzija sigurnosnog broja {index,number} od {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Označi kao provjereno", @@ -663,33 +747,41 @@ "messageformat": "PoniĆĄti provjeru", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Za provjeru sveobuhvatne enkripcije s kontaktom {name}, usporedite gore navedene brojeve s uređajem vaĆĄeg sugovornika. Također, vaĆĄ kontakt moĆŸe skenirati vaĆĄ kĂŽd svojim uređajem.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Saznajte viĆĄe", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Za provjeru sveobuhvatne enkripcije s kontaktom {name}, poveĆŸite gornju karticu u boji s uređajem vaĆĄeg sugovornika i usporedite brojeve. Ako se brojevi ne podudaraju, pokuĆĄajte s drugim parom sigurnosnih brojeva. Samo jedan par mora odgovarati.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Za provjeru sveobuhvatne enkripcije s kontaktom {name}, usporedite gore navedene brojeve s uređajem vaĆĄeg sugovornika. Također, vaĆĄ kontakt moĆŸe skenirati vaĆĄ kĂŽd svojim uređajem.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Promjene u vezi sigurnosnih brojeva", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Sigurnosni brojevi se trenutno aĆŸuriraju tijekom prijelaznog razdoblja kako bi se omogućile predstojeće značajke privatnosti u Signalu.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Da biste provjerili sigurnosne brojeve, uskladite karticu u boji s uređajem vaĆĄeg kontakta. Ako se brojevi ne podudaraju, pokuĆĄajte s drugim parom sigurnosnih brojeva. Samo jedan par mora odgovarati.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Trebate pomoć?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Shvaćam", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Nakon ĆĄto razmijenite poruke s ovom osobom, stvorit će se vaĆĄ sigurnosni broj.", @@ -1267,10 +1359,6 @@ "messageformat": "PrikaĆŸi nedavne medijske zapise", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Za provjeru sveobuhvatne enkripcije s kontaktom {name}, usporedite gore navedene brojeve s uređajem vaĆĄeg sugovornika. Također, vaĆĄ kontakt moĆŸe skenirati gornji QR kĂŽd .", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "JoĆĄ niste razmijenili nijednu poruku s ovim kontaktom. VaĆĄ zajednički sigurnosni broj će biti dostupan nakon prve poruke." }, @@ -1334,17 +1422,17 @@ "messageformat": "Detalji", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "IzbriĆĄi", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "IzbriĆĄi poruke", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "IzbriĆĄi razgovor?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Izbrisati poruke?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Ovaj razgovor će biti izbrisan s ovog uređaja.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Poruke iz ovog razgovora bit će izbrisane s ovog uređaja. I dalje moĆŸete pretraĆŸiti ovaj razgovor nakon ĆĄto izbriĆĄete poruke.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Napusti grupu", @@ -1438,6 +1526,14 @@ "messageformat": "VaĆĄa povijest poruka za oba razgovora spojena je i nalazi se ovdje.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "Broj {phoneNumber} pripada korisniku {conversationTitle}. Oboje ste članovi grupe {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "Broj {phoneNumber} pripada korisniku {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Sličica fotografije iz citirane poruke", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Nazovi ponovo", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Započni poziv", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "PridruĆŸi se pozivu", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon je isključen zbog velikog broja sudionika u pozivu", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Obavijesti o pozivima", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Poziv je pun", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "PridruĆŸi se", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Započni poziv", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Poziv je pun", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera je onemogućena", @@ -1621,10 +1725,6 @@ "messageformat": "Uključi kameru", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "UtiĆĄaj priču", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon je onemogućen", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Uključi mikrofon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Podijeli", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Prezentiranje je onemogućeno", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Zaustavi prezentiranje", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Zvono", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupa je prevelika za direktan poziv sudionika.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Omogući zvono", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Isključi zvono", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Uključi zvono", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ViĆĄe opcija", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Vi", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "VaĆĄa kamera je isključena", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "PrikaĆŸi sigurnosni broj", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Poruka", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "PrikaĆŸi sigurnosni broj", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Dohvaćanje telefonskog broja nije uspjelo. Provjerite internetsku vezu i pokuĆĄajte ponovo.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Poruke je moguće uređivati samo u roku od 3 sata od trenutka slanja.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Poruke je moguće uređivati samo u roku od 24 sata od trenutka slanja.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ova poruka je izbrisana.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Privitak je prevelik za prikazivanje.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Dio privitaka je prevelik za prikazivanje.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nije moguće učitati podatke o donaciji", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Samo u beta verziji Signala", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Uređivanje poruka dostupno je samo korisnicima beta verzije Signala. Ako uredite poruku, izmjene će biti vidljive samo osobama koje koriste najnoviju beta verziju Signala.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Uredi poruku", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Ako uredite poruku, izmjene će biti vidljive samo osobama koje koriste najnovije verzije Signala. Moći će vidjeti da ste uredili poruku.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Dolazni videopoziv
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Odlazni glasovni poziv", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Odlazni video poziv", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} vas zove", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Ponovno povezivanje
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} osoba} few {{count,number} osobe} many {{count,number} osoba} other {{count,number} osoba}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Glasovni poziv", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ZavrĆĄi poziv", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Napusti poziv", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon isključen", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon uključen", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zvono uključeno", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zvono isključeno", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Postavke", @@ -3468,13 +3668,25 @@ "messageformat": "Poziv preko cijelog zaslona", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Prebaci se na prikaz mreĆŸe", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Promijeni prikaz", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Prebaci se na prikaz govornika", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Prikaz reĆĄetke", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Prikaz bočne trake", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Prikaz govornika", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Prikaz je aĆŸuriran", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Napusti poziv", @@ -3576,6 +3788,14 @@ "messageformat": "U redu", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Poruku nije moguće urediti", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Poruku je moguće uređivati samo {max,number} puta.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "NaĆŸalost, ova sgnl:// poveznica je nevaĆŸeća!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Korisničko ime", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "DoĆĄlo je do pogreĆĄke s vaĆĄim korisničkim imenom – nije viĆĄe povezano s vaĆĄim računom.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "IzbriĆĄi korisničko ime", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Stvorite korisničko ime", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kĂŽd ili poveznica", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Potrebno je resetirati korisničko ime", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Potrebno je resetirati poveznicu s korisničkim imenom", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Podijelite svoje korisničko ime", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "IzbriĆĄi korisničko ime", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Jeste li sigurni? Ovo će ukloniti vaĆĄe korisničko ime, omogućujući drugim korisnicima da ga prisvoje.", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ovime ćete ukloniti svoje korisničko ime i poniĆĄtiti svoj QR kĂŽd i poveznicu. \"{username}\" bit će dostupno drugima za koriĆĄtenje. Sigurno ĆŸelite nastaviti?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ViĆĄe nećete moći dijeliti niti pregledavati priče. AĆŸuriranja priča koja ste nedavno podijelili također će se izbrisati.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Jezik", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Jezik", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Jezik sustava", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "PretraĆŸi jezike", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nema rezultata za \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Postavi", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Ponovno pokrenite Signal za promjenu", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Za promjenu jezika potrebno je ponovno pokrenuti aplikaciju.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ponovno pokreni", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Dostupno je aĆŸuriranje na verziju {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "DoĆĄlo je do pogreĆĄke prilikom spremanja vaĆĄih postavki. Molimo pokuĆĄajte ponovo.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Poruka", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ViĆĄe stilova", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "PoniĆĄti", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Gotovo", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Boja poveznice s korisničkim imenom, {index,number} od {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Ako poniĆĄtite svoj QR kĂŽd, trenutni QR kĂŽd i poveznica viĆĄe neće biti vaĆŸeći.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Ponovno postavljanje poveznice
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kĂŽd i poveznica nisu postavljeni. Provjerite mreĆŸnu vezu i pokuĆĄajte ponovno.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Postavite svoje korisničko ime za Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "uređeno", + "messageformat": "Uređeno", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "PoĆĄalji ponovo", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ViĆĄe radnji", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Pozivi", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Novi poziv", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Novi poziv", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ViĆĄe radnji", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "IzbriĆĄi povijest poziva", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Izbrisati povijest poziva?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Ovime ćete trajno izbrisati povijest poziva", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Ukloni", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Povijest poziva je izbrisana", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Kliknite za pregled ili novi poziv", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "PretraĆŸi", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtar: propuĆĄteni pozivi", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Prekidač", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nema nedavnih poziva. Nazovite prijatelja i započnite.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nema rezultata za \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Dolazni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Odlazni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "PropuĆĄteni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Grupni poziv", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nema nedavnih razgovora.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nema rezultata za \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Odlazni glasovni poziv} other {Dolazni glasovni poziv}}} Video {{direction, select, Outgoing {Odlazni video poziv} other {Dolazni video poziv}}} Group {{direction, select, Outgoing {Odlazni grupni poziv} other {Dolazni grupni poziv}}} other {{direction, select, Outgoing {Odlazni poziv} other {Dolazni poziv}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {PropuĆĄteni glasovni poziv} Video {PropuĆĄteni video poziv} Group {PropuĆĄten grupni poziv} other {PropuĆĄten poziv}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {PropuĆĄteni glasovni poziv} Video {PropuĆĄteni video poziv} Group {Grupni poziv bez odgovora} other {Glasovni poziv bez odgovora}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Odbijen glasovni poziv} Video {Odbijen videopoziv} Group {Odbijen grupni poziv} other {Odbijen poziv}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} osoba tipka.} few {{count,number} osobe tipkaju.} many {{count,number} osoba tipka.} other {{count,number} osoba tipka.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Novosti", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Manja podeĆĄavanja, ispravci greĆĄaka i poboljĆĄanje rada aplikacije. Hvala vam ĆĄto koristite Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ovo aĆŸuriranje uključuje poboljĆĄanja za glasovne pozive i video pozive te neka manja aĆŸuriranja dokumentacije. Hvala, {linkToGithub}!" + "icu:WhatsNew__v6.39--0": { + "messageformat": "Sada moĆŸete promijeniti odabrani jezik u Signalu bez mijenjanja postavki sustava (Postavke Signala > Izgled > Jezik)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "AĆŸurirali smo ikone obavijesti za grupe." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Ispravili smo kratak zastoj koji se ponekad događao u sustavu macOS tijekom pridruĆŸivanja čekaonici poziva." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Ispravili smo animaciju prijelaza videopločica prilikom pridruĆŸivanja grupnom pozivu ili napuĆĄtanja grupnog poziva." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Sada moĆŸete kliknuti na profilnu fotografiju ili grupni avatar u zaglavlju razgovora za brzi pristup postavkama razgovora ili pregledavanje novih priča u tom razgovoru. Hvala, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/hu/messages.json b/_locales/hu/messages.json index 0926298806..b286e67244 100644 --- a/_locales/hu/messages.json +++ b/_locales/hu/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "AdatbĂĄzishiba", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "AdatbĂĄzishiba törtĂ©nt. KimĂĄsolhatod a hibĂĄt, Ă©s kapcsolatba lĂ©phetsz a Signal ĂŒgyfĂ©lszolgĂĄlatĂĄval a problĂ©ma megoldĂĄsĂĄhoz. Ha azonnal hasznĂĄlnod kell a Signalt, törölheted az adataid, Ă©s ĂșjraindĂ­thatod.\n\nLĂ©pj kapcsolatba az ĂŒgyfĂ©lszolgĂĄlattal a következƑ cĂ­men: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Összes adat törlĂ©se Ă©s ĂșjraindĂ­tĂĄs", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Adatok törlĂ©se Ă©s ĂșjraindĂ­tĂĄs", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "VĂ©glegesen törlöd az összes adatot?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Az összes ĂŒzenetelƑzmĂ©ny Ă©s mĂ©diafĂĄjl vĂ©glegesen törlĂ©sre kerĂŒl errƑl az eszközrƑl. Az ĂșjbĂłli összekapcsolĂĄs utĂĄn hasznĂĄlhatod a Signalt ezen az eszközön. Ez nem törli az adatokat a telefonodrĂłl.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Az adatbĂĄzisod verziĂłja nem egyezik a Signal ezen verziĂłjĂĄval. GyƑzƑdj meg rĂłla, hogy a Signal legĂșjabb verziĂłjĂĄt nyitod meg a szĂĄmĂ­tĂłgĂ©peden.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&FĂĄjl", @@ -300,6 +316,70 @@ "messageformat": "CsevegĂ©sek", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Valami hiba törtĂ©nt a felhasznĂĄlĂłneveddel, mĂĄr nincs hozzĂĄrendelve a fiĂłkodhoz. MegprĂłbĂĄlhatod Ășjra beĂĄllĂ­tani, vagy vĂĄlaszthatsz egy Ășjat.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "JavĂ­tĂĄs most", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Hiba törtĂ©nt a felhasznĂĄlĂłnevedhez tartozĂł QR-kĂłddal Ă©s a hivatkozĂĄssal, ezĂ©rt azok mĂĄr nem Ă©rvĂ©nyesek. Hozz lĂ©tre egy Ășj hivatkozĂĄst Ă©s oszd meg mĂĄsokkal.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "JavĂ­tĂĄs most", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Lapok megjelenĂ­tĂ©se", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Lapok elrejtĂ©se", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Hiba lĂ©pett fel", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} olvasatlan", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "OlvasatlankĂ©nt megjelölve", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "CsevegĂ©sek", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "HĂ­vĂĄsok", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "TörtĂ©netek", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "BeĂĄllĂ­tĂĄsok", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal frissĂ­tĂ©se", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Vissza", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ezek a csevegĂ©sek archivĂĄlva vannak, ezĂ©rt csak akkor jelennek meg Ășjra a BeĂ©rkezƑ csevegĂ©sek között, ha Ășjabb ĂŒzenet Ă©rkezik.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "HĂ­vĂĄs ennek ellenĂ©re", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "CsatlakozĂĄs mindenkĂ©pp", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "HĂ­vĂĄs folytatĂĄsa", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "A biztonsĂĄgi szĂĄmok frissĂ­tĂ©se folyamatban van.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Tudj meg többet!", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ElƑzƑ biztonsĂĄgi szĂĄm", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "KövetkezƑ biztonsĂĄgi szĂĄm", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "BiztonsĂĄgi szĂĄm verziĂł, {index,number}/{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "MegjelölĂ©s ellenƑrzöttkĂ©nt", @@ -663,33 +747,41 @@ "messageformat": "EllenƑrzött ĂĄllapot törlĂ©se", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "A vĂ©gpontok közötti titkosĂ­tĂĄs ellenƑrzĂ©sĂ©hez {name} felhasznĂĄlĂłval, hasonlĂ­tsd össze a fent lĂĄthatĂł szĂĄmokat az Ƒ kĂ©szĂŒlĂ©kĂ©n megjelenƑ szĂĄmokkal. A kĂłdodat akĂĄr az Ƒ kĂ©szĂŒlĂ©kĂ©vel is beolvashatja.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Tudj meg többet!", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "A vĂ©gpontok közötti titkosĂ­tĂĄs ellenƑrzĂ©sĂ©hez {name} felhasznĂĄlĂłval, pĂĄrosĂ­tsd össze a fent lĂĄthatĂł szĂ­nkĂĄrtyĂĄt az Ƒ kĂ©szĂŒlĂ©kĂ©n megjelenƑ szĂ­nkĂĄrtyĂĄval, Ă©s hasonlĂ­tsd össze a szĂĄmokat. Ha nem egyeznek, prĂłbĂĄlkozz a mĂĄsik biztonsĂĄgi szĂĄmpĂĄrral. Csak egy pĂĄrnak kell egyeznie.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "A vĂ©gpontok közötti titkosĂ­tĂĄs ellenƑrzĂ©sĂ©hez {name} felhasznĂĄlĂłval, hasonlĂ­tsd össze a fent lĂĄthatĂł szĂĄmokat az Ƒ kĂ©szĂŒlĂ©kĂ©n megjelenƑ szĂĄmokkal. A kĂłdodat akĂĄr az Ƒ kĂ©szĂŒlĂ©kĂ©vel is beolvashatja.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "VĂĄltozĂĄsok a biztonsĂĄgi szĂĄmokban", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "A biztonsĂĄgi szĂĄmok egy ĂĄtmeneti idƑszak alatt frissĂŒlnek, hogy lehetƑvĂ© tegyĂ©k a Signal közelgƑ adatvĂ©delmi funkciĂłit.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "A biztonsĂĄgi szĂĄmok ellenƑrzĂ©sĂ©hez pĂĄrosĂ­tsd össze a szĂ­nkĂĄrtyĂĄt az Ƒ kĂ©szĂŒlĂ©kĂ©n megjelenƑ szĂ­nkĂĄrtyĂĄval. Ha nem egyeznek, prĂłbĂĄlkozz a mĂĄsik biztonsĂĄgi szĂĄmpĂĄrral. Csak egy pĂĄrnak kell egyeznie.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "SegĂ­tsĂ©gre van szĂŒksĂ©ged?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Rendben", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "A rendszer lĂ©trehoz egy biztonsĂĄgi szĂĄmot ezzel a szemĂ©llyel, miutĂĄn ĂŒzenetet vĂĄltott vele.", @@ -1267,10 +1359,6 @@ "messageformat": "Friss mĂ©diafĂĄjlok megtekintĂ©se", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "A vĂ©gpontok közötti titkosĂ­tĂĄs biztonsĂĄgĂĄnak ellenƑrzĂ©sĂ©hez {name} felhasznĂĄlĂłval, hasonlĂ­tsd össze a fent lĂĄthatĂł szĂĄmokat az Ƒ kĂ©szĂŒlĂ©kĂ©n megjelenƑ szĂĄmokkal. A fent lĂĄthatĂł QR-kĂłdot akĂĄr be is olvashatja.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "MĂ©g nem vĂĄltottĂĄl ĂŒzenetet ezzel a partnerrel. BiztonsĂĄgi szĂĄmod az elsƑ ĂŒzenet elkĂŒldĂ©sĂ©t követƑen lesz elĂ©rhetƑ." }, @@ -1334,17 +1422,17 @@ "messageformat": "RĂ©szletek", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "TörlĂ©s", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Üzenetek törlĂ©se", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "CsevegĂ©s törlĂ©se?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Üzenetek törlĂ©se?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "A csevegĂ©s ezen az eszközön törlĂ©sre kerĂŒl.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Az ebben a csevegĂ©sben lĂ©vƑ ĂŒzenetek törlƑdnek errƑl az eszközrƑl. Az ĂŒzenetek törlĂ©se utĂĄn tovĂĄbbra is rĂĄkereshetsz erre a csevegĂ©sre.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "KilĂ©pĂ©s a csoportbĂłl", @@ -1438,6 +1526,14 @@ "messageformat": "A kĂ©t csevegĂ©shez tartozĂł ĂŒzenetelƑzmĂ©nyek itt kerĂŒltek összevonĂĄsra.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "A(z) {phoneNumber} telefonszĂĄm a(z) {conversationTitle} beszĂ©lgetĂ©shez tartozik. Mindketten tagjai vagytok a(z) {sharedGroup} csoportnak.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "A(z) {phoneNumber} telefonszĂĄm a(z) {conversationTitle} beszĂ©lgetĂ©shez tartozik", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Az idĂ©zett ĂŒzenetben megjelenĂ­tett fotĂł elƑnĂ©zeti kĂ©pe", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ÚjrahĂ­vĂĄs", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "HĂ­vĂĄs indĂ­tĂĄsa", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "BelĂ©pĂ©s a hĂ­vĂĄsba", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "A rĂ©sztvevƑk nagy szĂĄma miatt a mikrofonod nĂ©mĂ­tva lett", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "HĂ­vĂĄsĂ©rtesĂ­tĂ©sek", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "A hĂ­vĂĄs megtelt", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "CsatlakozĂĄs", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "IndĂ­tĂĄs", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "A hĂ­vĂĄs megtelt", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera letiltva", @@ -1621,10 +1725,6 @@ "messageformat": "Kamera bekapcsolĂĄsa", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "NĂ©mĂ­tĂĄs", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon letiltva", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Mikrofon nĂ©mĂ­tĂĄsĂĄnak feloldĂĄsa", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "MegosztĂĄs", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "KĂ©pernyƑ-megosztĂĄs letiltva", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "KĂ©pernyƑ-megosztĂĄs leĂĄllĂ­tĂĄsa", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "CsengetĂ©s", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "A csoport tĂșl nagy ahhoz, hogy minden tagot fel lehessen hĂ­vni.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "CsengetĂ©s engedĂ©lyezĂ©se", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "CsengĂ©s kikapcsolĂĄsa", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "CsengĂ©s bekapcsolĂĄsa", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "TovĂĄbbi lehetƑsĂ©gek", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Te", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "A kamerĂĄd ki van kapcsolva", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "BiztonsĂĄgi szĂĄm megjelenĂ­tĂ©se", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Üzenet", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "BiztonsĂĄgi szĂĄm megjelenĂ­tĂ©se", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "A telefonszĂĄm lekĂ©rĂ©se sikertelen. EllenƑrizd a kapcsolatodat, majd prĂłbĂĄld Ășjra!", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "A mĂłdosĂ­tĂĄsokat csak az ĂŒzenet elkĂŒldĂ©sĂ©tƑl szĂĄmĂ­tott 3 ĂłrĂĄn belĂŒl lehet alkalmazni.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "A mĂłdosĂ­tĂĄsokat csak az ĂŒzenet elkĂŒldĂ©sĂ©tƑl szĂĄmĂ­tott 24 ĂłrĂĄn belĂŒl lehet alkalmazni.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ez az ĂŒzenet ki lett törölve.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "A mellĂ©klet tĂșl nagy a megjelenĂ­tĂ©shez.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Egyes mellĂ©kletek tĂșl nagyok a megjelenĂ­tĂ©shez.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nem sikerĂŒlt lekĂ©rni az adomĂĄny rĂ©szleteit", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "KizĂĄrĂłlag Signal bĂ©ta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Az ĂŒzenetek szerkesztĂ©se csak a Signal bĂ©ta felhasznĂĄlĂłi szĂĄmĂĄra Ă©rhetƑ el. Ha szerkesztesz egy ĂŒzenetet, azt csak azok lĂĄthatjĂĄk, akik a Signal bĂ©ta legĂșjabb verziĂłjĂĄt hasznĂĄljĂĄk.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Üzenet szerkesztĂ©se", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Ha szerkesztesz egy ĂŒzenetet, azt csak azok lĂĄthatjĂĄk, akik a Signal bĂ©ta legĂșjabb verziĂłjĂĄt hasznĂĄljĂĄk. Ɛk lĂĄtni fogjĂĄk, hogy szerkesztettĂ©l egy ĂŒzenetet.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "BejövƑ videĂłhĂ­vĂĄs
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "KimenƑ hanghĂ­vĂĄs", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "KimenƑ videĂłhĂ­vĂĄs", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} hĂ­v tĂ©ged", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ÚjracsatlakozĂĄs
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} szemĂ©ly} other {{count,number} szemĂ©ly}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "HanghĂ­vĂĄs", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "BefejezĂ©s", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "KilĂ©pĂ©s", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon ki", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon be", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "CsengĂ©s be", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "CsengĂ©s ki", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "BeĂĄllĂ­tĂĄsok", @@ -3468,13 +3668,25 @@ "messageformat": "HĂ­vĂĄs teljes kĂ©pernyƑre", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "VĂĄltĂĄs rĂĄcsos nĂ©zetre", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "NĂ©zet mĂłdosĂ­tĂĄsa", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "VĂĄltĂĄs beszĂ©lƑ nĂ©zetre", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "RĂĄcsos nĂ©zet", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "OldalsĂĄv nĂ©zet", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "BeszĂ©lƑ nĂ©zet", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "NĂ©zet frissĂ­tve", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "KilĂ©pĂ©s a hĂ­vĂĄsbĂłl", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Az ĂŒzenet nem szerkeszthetƑ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Csak {max,number} szerkesztĂ©s alkalmazhatĂł erre az ĂŒzenetre.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Sajnos ez a sgnl:// hivatkozĂĄs nem Ă©rtelmezhetƑ", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "FelhasznĂĄlĂłnĂ©v", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Valami hiba törtĂ©nt a felhasznĂĄlĂłneveddel, mĂĄr nincs hozzĂĄrendelve a fiĂłkodhoz.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "FelhasznĂĄlĂłnĂ©v törlĂ©se", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "FelhasznĂĄlĂłnĂ©v lĂ©trehozĂĄsa", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kĂłd vagy link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "A felhasznĂĄlĂłnevet vissza kell ĂĄllĂ­tani", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "A felhasznĂĄlĂłnĂ©vhez tartozĂł hivatkozĂĄst vissza kell ĂĄllĂ­tani", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "FelhasznĂĄlĂłnĂ©v megosztĂĄsa", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "FelhasznĂĄlĂłnĂ©v törlĂ©se", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Ezzel eltĂĄvolĂ­tod a felhasznĂĄlĂłnevedet, ami Ă­gy mĂĄs szĂĄmĂĄra elĂ©rhetƑvĂ© vĂĄlik. Biztos vagy benne?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ezzel eltĂĄvolĂ­tod a felhasznĂĄlĂłneved, Ă©s Ă©rvĂ©nytelennĂ© teszed a QR-kĂłdot Ă©s a hivatkozĂĄst. A(z) „ {username}” nĂ©v elĂ©rhetƑ lesz mĂĄs felhasznĂĄlĂłk szĂĄmĂĄra. Biztos vagy benne?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "TöbbĂ© nem fogsz tudni megosztani vagy megtekinteni TörtĂ©neteket. A közelmĂșltban megosztott TörtĂ©nettel kapcsolatos mĂłdosĂ­tĂĄsok is törlƑdnek.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Nyelv", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Nyelv", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Rendszernyelv", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Nyelvek keresĂ©se", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nincs talĂĄlat a következƑre: „{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "BeĂĄllĂ­tĂĄs", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Az alkalmazĂĄshoz indĂ­tsa Ășjra a Signalt", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "A nyelv mĂłdosĂ­tĂĄsĂĄhoz az alkalmazĂĄst Ășjra kell indĂ­tani.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ÚjraindĂ­tĂĄs", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ElĂ©rhetƑ frissĂ­tĂ©s a {version} verziĂłra", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Nem sikerĂŒlt elmenteni a beĂĄllĂ­tĂĄsokat. PrĂłbĂĄld Ășjra!", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Üzenet", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Több stĂ­lus", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "VisszaĂĄllĂ­tĂĄs", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "BefejezĂ©s", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "FelhasznĂĄlĂłnĂ©vhez tartozĂł hivatkozĂĄs szĂ­ne, {index,number}/{total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Ha visszaĂĄllĂ­tod a QR-kĂłdod, a meglĂ©vƑ QR-kĂłd Ă©s hivatkozĂĄs többĂ© nem fog mƱködni.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "HivatkozĂĄs visszaĂĄllĂ­tĂĄsa
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "A QR-kĂłd Ă©s a hivatkozĂĄs nincs beĂĄllĂ­tva. EllenƑrizd a hĂĄlĂłzati kapcsolatot, Ă©s prĂłbĂĄld Ășjra!", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ÁllĂ­tsd be a Signal-felhasznĂĄlĂłneved", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "szerkesztve", + "messageformat": "Szerkesztve", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ÚjrakĂŒldĂ©s", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "TovĂĄbbi tevĂ©kenysĂ©gek", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "HĂ­vĂĄsok", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Új hĂ­vĂĄs", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Új hĂ­vĂĄs", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "TovĂĄbbi tevĂ©kenysĂ©gek", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "HĂ­vĂĄselƑzmĂ©nyek törlĂ©se", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "HĂ­vĂĄselƑzmĂ©nyek törlĂ©se?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Ezzel vĂ©glegesen törlöd az összes hĂ­vĂĄselƑzmĂ©nyt", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "TörlĂ©s", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "HĂ­vĂĄs naplĂł törölve", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "A hĂ­vĂĄs megtekintĂ©sĂ©hez vagy indĂ­tĂĄsĂĄhoz kattints ide", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "KeresĂ©s", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "SzƱrĂ©s nem fogadott hĂ­vĂĄs szerint", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "VĂĄltĂĄs", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nincsenek legutĂłbbi hĂ­vĂĄsok. ElƑször hĂ­vd fel egy ismerƑsödet.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nincs talĂĄlat a következƑre: „{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "BejövƑ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "KimenƑ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Nem fogadott", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "CsoporthĂ­vĂĄs", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nincsenek legutĂłbbi beszĂ©lgetĂ©sek.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nincs talĂĄlat a következƑre: „{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {KimenƑ hanghĂ­vĂĄs} other {BejövƑ hanghĂ­vĂĄs}}} Video {{direction, select, Outgoing {KimenƑ videĂłhĂ­vĂĄs} other {BejövƑ videĂłhĂ­vĂĄs}}} Group {{direction, select, Outgoing {KimenƑ csoportos hĂ­vĂĄs} other {BejövƑ csoportos hĂ­vĂĄs}}} other {{direction, select, Outgoing {KimenƑ hĂ­vĂĄs} other {BejövƑ hĂ­vĂĄs}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Nem fogadott hanghĂ­vĂĄs} Video {Nem fogadott videĂłhĂ­vĂĄs} Group {Nem fogadott csoporthĂ­vĂĄs} other {Nem fogadott hĂ­vĂĄs}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Nem fogadott hanghĂ­vĂĄs} Video {Nem fogadott videĂłhĂ­vĂĄs} Group {Nem fogadott csoporthĂ­vĂĄs} other {Nem fogadott hĂ­vĂĄs}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ElutasĂ­tott hanghĂ­vĂĄs} Video {ElutasĂ­tott videohĂ­vĂĄs} Group {ElutasĂ­tott csoporthĂ­vĂĄs} other {ElutasĂ­tott hĂ­vĂĄs}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} mĂĄsik szemĂ©ly Ă­r.} other {{count,number} mĂĄsik szemĂ©ly Ă­r.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ÚjdonsĂĄgok", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "AprĂł finomĂ­tĂĄsok, hibajavĂ­tĂĄsok Ă©s teljesĂ­tmĂ©nynövelĂ©sek. KöszönjĂŒk, hogy a Signalt hasznĂĄlod!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ennek a frissĂ­tĂ©snek hĂĄla jobb hang- Ă©s videohĂ­vĂĄsok vĂĄrnak, valamint nĂ©hĂĄny kisebb dokumentĂĄciĂłfrissĂ­tĂ©st is vĂ©grehajtottunk (köszönjĂŒk {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "MostantĂłl a rendszerbeĂĄllĂ­tĂĄsok mĂłdosĂ­tĂĄsa nĂ©lkĂŒl mĂłdosĂ­thatod a kivĂĄlasztott nyelvet a Signal alkalmazĂĄsban (Signal-beĂĄllĂ­tĂĄsok > MegjelenĂ©s > Nyelv)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "MĂłdosĂ­tottuk az ikonokat nĂ©hĂĄny csoportfrissĂ­tĂ©snĂ©l." + "icu:WhatsNew__v6.39--1": { + "messageformat": "KijavĂ­tottunk egy rövid kĂ©sĂ©st, ami nĂ©ha macOS-en fordult elƑ a hĂ­vĂĄs elƑtti vĂĄrakoztatĂł tĂ©rhez valĂł csatlakozĂĄst követƑen." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "JavĂ­tottuk a videocsempĂ©k ĂĄtmeneti animĂĄciĂłjĂĄt, amikor valaki csatlakozik a csoporthĂ­vĂĄshoz, vagy elhagyja azt." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "MostantĂłl a csevegĂ©s fejlĂ©cĂ©ben rĂĄkattinthatsz egy profilfotĂłra vagy a csoport avatarjĂĄra, hogy gyorsan elĂ©rd a csevegĂ©si beĂĄllĂ­tĂĄsokat, vagy megtekinthesd a csevegĂ©sbƑl szĂĄrmazĂł mĂ©g nem lĂĄtott törtĂ©neteket. Köszi, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/id/messages.json b/_locales/id/messages.json index 38b4ca519e..25f2ae1630 100644 --- a/_locales/id/messages.json +++ b/_locales/id/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Kesalahan Basis Data", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Terjadi kesalahan pada basis data. Anda dapat menyalin kode kesalahan dan menghubungi dukungan Signal untuk membantu mengatasi masalah ini. Jika Anda perlu segera menggunakan Signal, Anda dapat menghapus data Anda dan memulai ulang.\n\nHubungi dukungan dengan membuka: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Hapus semua data dan mulai ulang", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Hapus data dan mulai ulang", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Hapus semua data secara permanen?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Semua riwayat pesan dan media Anda akan dihapus secara permanen dari perangkat ini. Anda akan dapat menggunakan Signal di perangkat ini setelah menyambungkannya kembali. Ini tidak akan menghapus data apa pun dari ponsel Anda.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Versi basis data Anda tidak cocok dengan versi Signal ini. Pastikan Anda membuka Signal versi terbaru di komputer Anda.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Berkas", @@ -300,6 +316,70 @@ "messageformat": "Obrolan", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Ada yang salah dengan nama pengguna Anda, nama pengguna tersebut sudah tidak ditetapkan untuk akun Anda. Anda bisa mencoba dan mengaturnya lagi atau memilih nama baru.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Perbaiki sekarang", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Ada yang salah dengan kode QR dan tautan nama pengguna Anda, tautan tersebut sudah tidak valid. Buat tautan baru untuk dibagikan dengan orang lain.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Perbaiki sekarang", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Tampilkan Tab", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Sembunyikan Tab", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Terjadi kesalahan", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} belum dibaca", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Ditandai belum dibaca", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Obrolan", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Panggilan", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Cerita", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Pengaturan", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Perbarui Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Kembali", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Obrolan ini diarsipkan dan hanya akan muncul di Kotak Masuk jika ada pesan baru diterima.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Tetap panggil", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Lanjut bergabung", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Lanjutkan Panggilan", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Nomor keamanan sedang diperbarui.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Pelajari lebih lanjut", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Nomor Keamanan sebelumnya", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Nomor Keamanan berikutnya", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Versi Nomor Keamanan, {index,number} dari {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Tandai sebagai terverifikasi", @@ -663,33 +747,41 @@ "messageformat": "Hapus verifikasi", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Untuk memverifikasi enkripsi end-to-end dengan {name}, bandingkan nomor di atas dengan perangkat mereka. Mereka juga bisa memindai kode Anda dengan perangkat mereka.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Pelajari selengkapnya", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Untuk memverifikasi enkripsi end-to-end dengan {name}, cocokkan kartu warna di atas dengan perangkat mereka dan bandingkan nomornya. Jika tidak cocok, coba pasangan nomor keamanan lain. Hanya satu pasang yang harus cocok.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Untuk memverifikasi enkripsi end-to-end dengan {name}, bandingkan nomor di atas dengan perangkat mereka. Mereka juga bisa memindai kode Anda dengan perangkat mereka.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Perubahan pada Nomor Keamanan", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Nomor keamanan sedang diperbarui selama periode transisi agar dapat mengaktifkan fitur privasi yang akan datang di Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Untuk memverifikasi nomor keamanan, cocokkan kartu warna dengan perangkat milik kontak Anda. Jika tidak cocok, coba pasangan nomor keamanan lain. Hanya satu pasang yang harus cocok.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Butuh bantuan?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Mengerti", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Nomor keamanan akan dibuat dengan orang ini setelah Anda bertukar pesan dengannya.", @@ -1267,10 +1359,6 @@ "messageformat": "Lihat media terbaru", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Untuk memverifikasi keamanan enkripsi end-to-end Anda dengan {name}, bandingkan nomor di atas dengan perangkat mereka. Mereka juga bisa memindai kode QR di atas.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Anda belum mengirim pesan apapun dengan kontak ini. Nomor keamanan Anda dengan kontak ini akan tersedia sesaat setelah pesan pertama." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Hapus", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Hapus pesan", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Hapus obrolan?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Hapus pesan?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Obrolan ini akan dihapus dari perangkat ini.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Pesan dalam obrolan ini akan dihapus dari perangkat. Anda masih bisa mencari obrolan ini setelah menghapus pesan.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Keluar grup", @@ -1438,6 +1526,14 @@ "messageformat": "Riwayat pesan Anda untuk kedua obrolan telah digabungkan di sini.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} milik dari {conversationTitle}. Kalian berdua adalah anggota dari {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} milik dari {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Cuplikan gambar dari pesan yang dikutip", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Telepon lagi", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Mulai Panggilan", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Bergabung Panggilan", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon dibisukan karena ukuran panggilan", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Notifikasi panggilan", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Panggilan penuh", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Gabung", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Mulai", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Panggilan penuh", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera dinonaktifkan", @@ -1621,10 +1725,6 @@ "messageformat": "Nyalakan kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Bisukan", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon dinonaktifkan", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Bunyikan mikrofon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Bagikan", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Presentasi dinonaktifkan", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Hentikan berbagi layar", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Dering", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grup terlalu besar untuk menghubungi peserta", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Aktifkan dering", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Nonaktifkan dering", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Aktifkan dering", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Opsi lainnya", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Anda", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kamera Anda mati", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Lihat Nomor Keamanan", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Pesan", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Lihat Nomor Keamanan", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Gagal mengambil nomor telepon. Periksa koneksi internet dan coba lagi.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Pengeditan hanya dapat diterapkan dalam rentang waktu 3 jam sejak Anda mengirimkan pesan ini.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Pengeditan hanya dapat diterapkan dalam rentang waktu 24 jam sejak Anda mengirimkan pesan ini.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Pesan ini telah dihapus.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Lampiran terlalu besar untuk ditampilkan.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Beberapa lampiran terlalu besar untuk ditampilkan.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Tidak dapat mengambil detail donasi", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Khusus versi Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Fitur Edit Pesan hanya tersedia bagi pengguna Signal beta. Jika Anda mengedit pesan, pengeditan hanya bisa terlihat oleh pengguna Signal beta versi terbaru.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Edit Pesan", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Jika Anda mengedit pesan, pengeditan hanya bisa terlihat oleh pengguna Signal versi terbaru. Mereka akan dapat melihat bahwa Anda telah mengedit pesan.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Panggilan video masuk
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Panggilan suara keluar", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Panggilan video keluar", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} memanggil Anda", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Menghubungkan ulang
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} orang}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Panggilan audio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Akhiri", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Keluar", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mik mati", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mik nyala", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Dering aktif", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Dering nonaktif", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Pengaturan", @@ -3468,13 +3668,25 @@ "messageformat": "Tampilkan panggilan di layar penuh", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Beralih ke tampilan grid", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Ubah tampilan", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Beralih ke tampilan pembicara", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Tampilan grid", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Tampilan bilah samping", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Tampilan pembicara", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Tampilan diperbarui", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Tinggalkan panggilan", @@ -3576,6 +3788,14 @@ "messageformat": "Oke", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Tidak dapat mengedit pesan", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Hanya {max,number} editan yang bisa diterapkan pada pesan ini.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Maaf, tautan sgnl:// tidak dapat dibuka!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nama Pengguna", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Ada yang salah dengan nama pengguna Anda, nama pengguna tersebut sudah tidak ditetapkan untuk akun Anda.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Hapus nama pengguna", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Buat Nama Pengguna", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Kode QR atau Tautan", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Nama pengguna perlu direset", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Tautan nama pengguna perlu direset", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Bagikan Nama Pengguna Anda", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Hapus nama pengguna", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Ini akan menghapus nama pengguna Anda, dan memungkinkan pengguna lain untuk memakainya. Apakah Anda yakin?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ini akan menghapus nama pengguna serta menonaktifkan tautan dan kode QR Anda. “{username}” akan bisa diklaim oleh orang lain. Anda yakin?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Anda tidak bisa lagi membagikan atau melihat cerita. Pembaruan cerita yang baru-baru ini Anda bagikan juga akan dihapus.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Bahasa", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Bahasa", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Bahasa Sistem", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Cari bahasa", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Tidak ada hasil untuk “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Atur", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Mulai ulang Signal untuk menerapkan", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Untuk mengubah bahasa, aplikasi perlu dimulai ulang.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Mulai ulang", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Pembaruan {version} tersedia", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Terjadi kesalahan saat menyimpan pengaturan Anda. Mohon coba lagi.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Pesan", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Gaya lainnya", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Atur ulang", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Selesai", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Warna tautan nama pengguna, {index,number} dari {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Jika Anda mereset kode QR, tautan dan kode QR lama Anda tidak akan berfungsi lagi.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Mereset tautan
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Kode QR dan tautan belum ditetapkan. Periksa koneksi internet Anda dan coba lagi.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Buat nama pengguna Signal Anda", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "diedit", + "messageformat": "Diedit", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Kirimkan kembali", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Aksi lainnya", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Panggilan", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Panggilan baru", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Panggilan baru", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Aksi lainnya", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Hapus riwayat panggilan", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Hapus riwayat panggilan?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Tindakan ini akan menghapus semua riwayat panggilan secara permanen", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Bersihkan", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Catatan Panggilan Dibersihkan", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klik untuk melihat atau memulai panggilan", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Cari", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filter berdasarkan tidak terjawab", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Beralih", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Tidak ada panggilan baru Mulai dengan menelepon teman.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Tidak ada hasil untuk “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Panggilan Masuk", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Panggilan Keluar", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Panggilan Tidak Terjawab", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Panggilan grup", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Tidak ada percakapan terkini.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Tidak ada hasil untuk “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Panggilan suara keluar} other {Panggilan suara masuk}}} Video {{direction, select, Outgoing {Panggilan video keluar} other {Panggilan video masuk}}} Group {{direction, select, Outgoing {Panggilan grup keluar} other {Panggilan grup masuk}}} other {{direction, select, Outgoing {Panggilan keluar} other {Panggilan masuk}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Panggilan suara tidak terjawab} Video {Panggilan video tidak terjawab} Group {Panggilan grup tak terjawab} other {Panggilan tidak terjawab}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Panggilan suara tidak terjawab} Video {Panggilan video tidak terjawab} Group {Panggilan grup tidak terjawab} other {Panggilan tidak terjawab}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Panggilan suara ditolak} Video {Panggilan video ditolak} Group {Panggilan grup ditolak} other {Panggilan ditolak}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number} orang lainnya sedang mengetik.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Yang Baru", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Tambahan penyesuaian kecil, perbaikan bug, dan peningkatan performa. Terima kasih telah menggunakan Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Pembaruan ini mencakup beberapa peningkatan untuk panggilan suara dan video, dan beberapa pembaruan kecil pada dokumentasi (terima kasih, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Sekarang Anda dapat mengubah bahasa pilihan di Signal tanpa mengubah pengaturan sistem (Pengaturan Signal > Tampilan > Bahasa)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Kami memperbarui beberapa ikon notifikasi grup." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Kami memperbaiki keterlambatan singkat yang kadang terjadi di macOS setelah bergabung di lobi panggilan." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Kami memperbaiki animasi transisi untuk tile video saat seseorang bergabung atau keluar dari panggilan grup." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Kini Anda dapat mengeklik foto profil atau avatar grup di tajuk obrolan untuk mengakses pengaturan obrolan dengan cepat atau melihat cerita yang belum dilihat dari obrolan tersebut. Terima kasih, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/it/messages.json b/_locales/it/messages.json index ebb3f3df6e..44320c7a85 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Errore del database", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Si Ăš verificato un errore nel database. Puoi copiare il codice dell'errore e contattare il supporto di Signal per aiutarci a risolvere il problema. Se hai bisogno di usare subito Signal, puoi sempre eliminare i tuoi dati e riavviarlo.\n\nContatta il nostro supporto al seguente link: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Elimina tutti i dati e riavvia", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Elimina dati e riavvia", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Rimuovere definitivamente tutti i dati?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Tutta la tua cronologia messaggi e media verrĂ  eliminata in modo permanente da questo dispositivo. Potrai continuare a usare Signal su questo dispositivo dopo che l'avrai ricollegato. Questa azione non comporterĂ  l'eliminazione dei dati dal tuo telefono.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "La versione del tuo database non combacia con questa versione di Signal. Accertati di stare usando la versione piĂč recente di Signal sul tuo computer.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&File", @@ -300,6 +316,70 @@ "messageformat": "Chat", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Si Ăš verificato un errore con il tuo nome utente: non Ăš piĂč assegnato al tuo account. Puoi provare a reimpostarlo oppure sceglierne un altro.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Risolvi ora", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Si Ăš verificato un errore con il tuo codice QR e link del nome utente: ora non sono piĂč validi. Crea un nuovo link per condividerlo con altre persone.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Risolvi ora", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Mostra schede di navigazione", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Nascondi schede di navigazione", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ops, qualcosa Ăš andato storto
", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} non letti", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Segnato come non letto", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chat", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Chiamate", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Storie", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Impostazioni", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Aggiorna Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profilo", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Indietro", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Queste chat sono archiviate e compariranno nella lista delle chat solo se arriveranno nuovi messaggi.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Chiama comunque", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Partecipa lo stesso", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continua chiamata", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Stiamo aggiornando i codici di sicurezza.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Scopri di piĂč", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Codice di sicurezza precedente", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Codice di sicurezza successivo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Versione del codice di sicurezza, {index,number} di {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Segna come verificato", @@ -663,33 +747,41 @@ "messageformat": "Rimuovi verifica", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Per verificare la sicurezza della tua crittografia end-to-end con {name}, confronta i numeri qui in alto con quelli sul dispositivo dell'altra persona. È possibile scansionare il tuo codice qui sopra per velocizzare il processo.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Scopri di piĂč", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Per verificare la sicurezza della tua crittografia end-to-end con {name}, fai combaciare i codici di sicurezza presenti sulla scheda colorata che vedi con quelli presenti sulla scheda colorata dell'altra persona. Se i codici non combaciano, continua a scorrere e prova un'altra coppia di codici di sicurezza. Ricorda che deve combaciare una sola coppia.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Per verificare la sicurezza della tua crittografia end-to-end con {name}, confronta i numeri qui in alto con quelli sul dispositivo dell'altra persona. È possibile scansionare il tuo codice qui sopra per velocizzare il processo.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Cambiamenti nei codici di sicurezza", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Stiamo aggiornando il sistema dei codici di sicurezza in vista di un periodo di transizione che ci porterĂ  a introdurre nuove funzioni per la privacy su Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Per verificare i codici di sicurezza, fai combaciare i codici di sicurezza presenti sulla scheda colorata che vedi con quelli presenti sulla scheda colorata che vede l'altra persona. Se i codici non combaciano, continua a scorrere e prova un'altra coppia di codici di sicurezza. Ricorda che deve combaciare una sola coppia.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Hai bisogno di aiuto?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Capito", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "VerrĂ  creato un codice di sicurezza per questa persona dopo che avrai inviato dei messaggi in chat.", @@ -1267,10 +1359,6 @@ "messageformat": "Visualizza i media recenti", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Per verificare la sicurezza della tua crittografia end-to-end con {name}, confronta i numeri qui sopra con quelli che vedono loro sul proprio dispositivo. È possibile scansionare il codice QR qui sopra per velocizzare il processo.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Non hai ancora scambiato alcun messaggio con questo contatto. Il codice di sicurezza sarĂ  disponibile dopo il primo messaggio." }, @@ -1334,17 +1422,17 @@ "messageformat": "Informazioni", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Elimina", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Elimina messaggi", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Vuoi eliminare la chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Vuoi davvero eliminare i messaggi?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Questa chat verrĂ  eliminata da questo dispositivo.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "I messaggi in questa chat verranno rimossi dal dispositivo. Dopo che avrai eliminato i messaggi, questa chat apparirĂ  comunque nei risultati delle tue ricerche.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Abbandona il gruppo", @@ -1438,6 +1526,14 @@ "messageformat": "La cronologia dei messaggi di entrambe le chat Ăš stata unita e puoi trovarla qui.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} appartiene a {conversationTitle}. Fate parte di questo gruppo: {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} appartiene a {conversationTitle}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Anteprima dell'immagine dal messaggio citato", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Richiama", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Inizia chiamata", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Unisciti alla chiamata", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Microfono disattivato visto il numero di utenti nella chiamata", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Notifiche di chiamata", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "La chiamata Ăš piena", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Camera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Unisciti", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Inizia", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Chiamata piena", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Camera disattivata", @@ -1621,10 +1725,6 @@ "messageformat": "Attiva camera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silenzia", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microfono disattivato", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Riattiva microfono", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Condividi", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Presentazione disattivata", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Interrompi la presentazione", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Squilla", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Il gruppo Ăš troppo grande per squillare ai partecipanti.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Attiva squillo", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Disattiva squillo chiamata", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Attiva squillo chiamata", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "PiĂč opzioni", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Tu", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "La tua videocamera Ăš disattivata", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Visualizza numero di sicurezza", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Messaggio", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Visualizza numero di sicurezza", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Impossibile recuperare il numero di telefono. Controlla la tua connessione e riprova.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Puoi modificare questo messaggio entro 3 ore dall'invio.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Puoi modificare questo messaggio solo entro 24 ore dall'invio.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Questo messaggio Ăš stato eliminato.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Allegato troppo grande per essere visualizzato.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Alcuni allegati sono troppo grandi per essere visualizzati.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Impossibile recuperare i dettagli della donazione", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Solo per la beta di Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "La funzione di modifica dei messaggi Ăš disponibile solo agli utenti della beta di Signal. Se modifichi un messaggio, la modifica sarĂ  visibile solamente alle persone che stanno usando la versione piĂč recente della beta di Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Modifica messaggio", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Se modifichi un messaggio, la modifica sarĂ  visibile solamente alle persone che usano la versione piĂč recente di Signal. Potranno quindi vedere che hai effettuato una modifica.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Videochiamata in arrivo
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Chiamata in uscita", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Videochiamata in uscita", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ti sta chiamando", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Riconnessione
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} persona} other {{count,number} persone}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Chiamata vocale", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Termina", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Abbandona", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Microfono disattivato", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Microfono attivato", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Squillo chiamata attivato", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Squillo chiamata disattivato", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Impostazioni", @@ -3468,13 +3668,25 @@ "messageformat": "Chiamata a schermo intero", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Passa alla visualizzazione a griglia", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Cambia layout", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Passa alla visualizzazione oratore", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Griglia", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Barra laterale", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Speaker al centro", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Layout aggiornato", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Termina", @@ -3576,6 +3788,14 @@ "messageformat": "Ok", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Impossibile modificare il messaggio", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Puoi effettuare solo {max,number} modifiche a questo messaggio.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Spiacenti, questo link sgnl:// non ha senso!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nome utente", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Si Ăš verificato un errore con il tuo nome utente: non Ăš piĂč assegnato al tuo account.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Elimina nome utente", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Crea nome utente", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Codice QR o link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Il nome utente deve essere reimpostato", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Il link nome utente deve essere reimpostato", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Condividi il tuo nome utente", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Elimina nome utente", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Questo rimuoverĂ  il tuo nome utente, permettendo ad altri utenti di usarlo. Vuoi procedere comunque?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Quest'azione porterĂ  alla rimozione del tuo nome utente e disattiverĂ  il tuo codice QR e link. \"{username}\" sarĂ  disponibile come nome utente per altre persone. Vuoi procedere comunque?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Non potrai piĂč condividere o vedere le Storie. Verranno eliminati tutti gli aggiornamenti legati alle Storie che hai pubblicato di recente.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Lingua", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Lingua", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Lingua di sistema", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Cerca lingua", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nessun risultato per \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Imposta", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Riavvia Signal per aggiornare", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Per modificare la lingua, l'app deve essere riavviata.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Riavvia", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Aggiornamento alla versione {version} disponibile", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Si Ăš verificato un errore durante il salvataggio delle impostazioni. Si prega di riprovare.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Messaggio", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "PiĂč stili", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Resetta", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Fatto", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Colore link del nome utente, {index,number} di {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Se fai il reset del tuo codice QR, il codice QR e il link attuali smetteranno di funzionare.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Reset del link in corso
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Codice QR e link non impostati. Controlla la tua connessione di rete e riprova.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Imposta il tuo nome utente per Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "modificato", + "messageformat": "Modificato", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Invia di nuovo", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "PiĂč azioni", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Chiamate", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nuova chiamata", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nuova chiamata", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "PiĂč azioni", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Elimina cronologia chiamate", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Vuoi eliminare la cronologia delle chiamate?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Quest'azione rimuoverĂ  per sempre tutta la cronologia delle chiamate", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Rimuovi", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Cronologia chiamate eliminata", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Clicca per visualizzare o iniziare una chiamata", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Cerca", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtra per chiamate perse", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Aziona", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nessuna chiamata recente. Inizia chiamando un tuo amico o amica.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nessun risultato per \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "In arrivo", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "In uscita", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Chiamata persa", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Chiamata di gruppo", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nessuna conversazione recente.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nessun risultato per \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Chiamata in uscita} other {Chiamata in arrivo}}} Video {{direction, select, Outgoing {Videochiamata in uscita} other {Videochiamata in arrivo}}} Group {{direction, select, Outgoing {Chiamata di gruppo in uscita} other {Chiamata di gruppo in entrata}}} other {{direction, select, Outgoing {Chiamata in uscita} other {Chiamata in entrata}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Chiamata persa} Video {Videochiamata persa} Group {Chiamata di gruppo persa} other {Chiamata persa}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Chiamata senza risposta} Video {Videochiamata senza risposta} Group {Chiamata di gruppo persa} other {Chiamata persa}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Chiamata vocale rifiutata} Video {Videochiamata rifiutata} Group {Chiamata di gruppo rifiutata} other {Chiamata rifiutata}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} persona sta scrivendo.} other {{count,number} persone stanno scrivendo.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Cosa c'Ăš di nuovo", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Altre piccole modifiche e correzioni di bug per far funzionare l'app senza problemi. Grazie per usare Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Questo aggiornamento include una serie di miglioramenti per le chiamate vocali e video, oltre a degli aggiornamenti minori nella documentazione di Signal (grazie, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Da ora puoi modificare la lingua su Signal senza cambiare le impostazioni di sistema del tuo dispositivo (Impostazioni di Signal > Aspetto > Lingua)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Abbiamo modificato le icone delle notifiche che appaiono per le novitĂ  nei gruppi, ad esempio quando viene aggiunta una nuova persona. Queste icone migliorano la leggibilitĂ  dei testi, specialmente se sei fan del lato oscuro della forza
 e del tema di Signal. Provare per credere!" + "icu:WhatsNew__v6.39--1": { + "messageformat": "Abbiamo risolto un problema di lag che poteva capitare quando si entrava in una chiamata di gruppo su dispositivi macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Abbiamo aggiornato la transizione animata per le schermate video quando una persona si unisce a una chiamata di gruppo o la abbandona. Adesso sarĂ  piĂč semplice rimanere al passo con il continuo viavai di persone!" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Da ora puoi cliccare sulla foto di un profilo o sull'avatar di un gruppo nella parte superiore della chat per accedere subito alle impostazioni della chat o per recuperare le Storie non ancora visualizzate. Grazie, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index 9bbb02ec7d..14bcdd2104 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ăƒ‡ăƒŒă‚żăƒ™ăƒŒă‚čăźă‚šăƒ©ăƒŒ", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ăƒ‡ăƒŒă‚żăƒ™ăƒŒă‚čă‚šăƒ©ăƒŒăŒç™șç”Ÿă—ăŸă—ăŸă€‚ă‚šăƒ©ăƒŒă‚’ă‚łăƒ”ăƒŒă—ăŠSignală‚”ăƒăƒŒăƒˆăžé€Łç”Ąă™ă‚‹ăšă€ć•éĄŒăźè§Łæ±șにćœčç«‹ăŠă‚‹ă“ăšăŒă§ăăŸă™ă€‚ă™ăă«Signală‚’äœżç”šă™ă‚‹ćż…èŠăŒă‚ă‚‹ć ŽćˆăŻă€ăƒ‡ăƒŒă‚żă‚’æ¶ˆćŽ»ă—ăŠć†è”·ć‹•ă™ă‚‹ă“ăšăŒă§ăăŸă™ă€‚\n\nă‚”ăƒăƒŒăƒˆăžăźăŠć•ă„ćˆă‚ă›ăŻ{link}ăŸă§ăŠéĄ˜ă„ă—ăŸă™ă€‚", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "すăčăŠăźăƒ‡ăƒŒă‚żă‚’æ¶ˆćŽ»ă—ăŠć†è”·ć‹•", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "すăčăŠăźăƒ‡ăƒŒă‚żă‚’æ¶ˆćŽ»ă—ăŠć†è”·ć‹•ă™ă‚‹", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "すăčăŠăźăƒ‡ăƒŒă‚żă‚’ćźŒć…šă«æ¶ˆćŽ»ă—ăŸă™ă‹ïŒŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "過掻たすăčăŠăźăƒĄăƒƒă‚»ăƒŒă‚žăšăƒĄăƒ‡ă‚Łă‚ąăŻăŠäœżă„ăźç«Żæœ«ă‹ă‚‰ćźŒć…šă«æ¶ˆćŽ»ă•ă‚ŒăŸă™ă€‚ć†ăƒȘăƒłă‚Żă™ă‚‹ăšă€ă“ăźç«Żæœ«ă§Signală‚’äœżç”šă§ăă‚‹ă‚ˆă†ă«ăȘă‚ŠăŸă™ă€‚ă”ćˆ©ç”šäž­ăźă‚čăƒžăƒŒăƒˆăƒ•ă‚©ăƒłăźăƒ‡ăƒŒă‚żăŻæ¶ˆćŽ»ă•ă‚ŒăŸă›ă‚“ă€‚", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "ăƒ‡ăƒŒă‚żăƒ™ăƒŒă‚čăźăƒăƒŒă‚žăƒ§ăƒłăšă€é–‹ă„ăŸSignalăźăƒăƒŒă‚žăƒ§ăƒłăŒäž€è‡Žă—ăŸă›ă‚“ă€‚ ă”ćˆ©ç”šăźă‚łăƒłăƒ”ăƒ„ăƒŒă‚żăƒŒă§ă€æœ€æ–°ăƒăƒŒă‚žăƒ§ăƒłăźSignalを開いどいるかをおçąșかめください。", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "ăƒ•ă‚Ąă‚€ăƒ« (&F)", @@ -300,6 +316,70 @@ "messageformat": "チャット", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă«ć•éĄŒăŒç™șç”Ÿă—ăŸăŸă‚ă€ă‚ąă‚«ă‚Šăƒłăƒˆă«ć‰Čă‚Šćœ“ăŠă‚‰ă‚ŒăŠă„ăŸă›ă‚“ă€‚ă‚‚ă†äž€ćșŠèš­ćźšă—ç›Žă™ă‹ă€æ–°ă—ă„ă‚‚ăźă‚’éžă‚“ă§ăżăŠăă ă•ă„ă€‚", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ä»Šă™ăäżźæ­Łă™ă‚‹", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "QRă‚łăƒŒăƒ‰ăšăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăźăƒȘăƒłă‚Żă«ć•éĄŒăŒç™ș生したため、無ćŠčにăȘă‚ŠăŸă—ăŸă€‚æ–°ă—ă„ăƒȘăƒłă‚Żă‚’äœœæˆă—ăŠä»–ăźăƒŠăƒŒă‚¶ăƒŒăšć…±æœ‰ă—ăŠăă ă•ă„ă€‚", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ä»Šă™ăäżźæ­Łă™ă‚‹", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ă‚żăƒ–ă‚’èĄšç€șする", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "タブを隠す", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ă‚šăƒ©ăƒŒăŒç™șç”Ÿă—ăŸă—ăŸ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number}件たæœȘèȘ­ăƒĄăƒƒă‚»ăƒŒă‚ž", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "æœȘèȘ­ă«ă™ă‚‹", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "チャット", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "通話", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ă‚čăƒˆăƒŒăƒȘăƒŒ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "èš­ćźš", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signală‚’ă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆă™ă‚‹", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "æˆ»ă‚‹", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ă“ă‚Œă‚‰ăźăƒăƒŁăƒƒăƒˆăŻă‚ąăƒŒă‚«ă‚€ăƒ–ă•ă‚Œă€æ–°ă—ă„ăƒĄăƒƒă‚»ăƒŒă‚žă‚’ć—äżĄă—ăŸć Žćˆăźăżć—äżĄăƒˆăƒŹă‚€ă«èĄšç€șă•ă‚ŒăŸă™ă€‚", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ăšă«ă‹ăç™ș信する", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "それでも揂抠する", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "é€šè©±ă‚’ç¶šă‘ă‚‹", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "漉慹ç•Șć·ă‚’æ›Žæ–°äž­ă§ă™ă€‚", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ă•ă‚‰ă«è©łă—ă", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "才曞ぼ漉慹ç•Șć·", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "æŹĄăźćź‰ć…šç•Șć·", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "漉慹ç•Șć·ăźăƒăƒŒă‚žăƒ§ăƒłăŻă€ {total,number}た{index,number}です", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "æ€œèšŒæžˆăżă«ă™ă‚‹", @@ -663,33 +747,41 @@ "messageformat": "æœȘæ€œèšŒă«ă™ă‚‹", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} ăšăźă‚„ă‚Šăšă‚ŠăŒă‚šăƒłăƒ‰ăƒ„ăƒŒă‚šăƒłăƒ‰ă§æš—ć·ćŒ–ă•ă‚ŒăŠă„ă‚‹ă‹ă‚’æ€œèšŒă™ă‚‹ă«ăŻă€ăŠäș’ă„ăźç«Żæœ«ă§ă€äžŠèš˜ăźç•Șć·ăŒç›žæ‰‹ç«Żæœ«äžŠăźç•Șć·ăšćŒă˜ă‹çąșèȘă—ăŠăă ă•ă„ă€‚ç›žæ‰‹ăźç«Żæœ«ă§ă‚ăȘăŸăźă‚łăƒŒăƒ‰ă‚’ă‚čキャンしどもらうæ–čæł•ă‚‚ă‚ă‚ŠăŸă™ă€‚", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ă•ă‚‰ă«è©łă—ă", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name}ăšăźă‚„ă‚Šăšă‚ŠăŒă‚šăƒłăƒ‰ăƒ„ăƒŒă‚šăƒłăƒ‰ă§æš—ć·ćŒ–ă•ă‚ŒăŠă„ă‚‹ă‹ă‚’æ€œèšŒă™ă‚‹ă«ăŻă€ăŠäș’ă„ăźç«Żæœ«ă§ă€äžŠéƒšăźă‚«ăƒ©ăƒŒă‚«ăƒŒăƒ‰ïŒˆè‰ČăŒă€ă„ăŸæž ć†…ïŒ‰ăźæ•°ć­—ăŒäž€è‡Žă™ă‚‹ă‹ă‚’çąșèȘă—ăŠăă ă•ă„ă€‚æ•°ć­—ăŒäž€è‡Žă—ăȘă„ć ŽćˆăŻă€ćˆ„ăźćź‰ć…šç•Șć·ă‚’èĄšç€șă•ă›ăŠăă ă•ă„ă€‚äž€è‡Žă™ă‚‹æ•°ć­—ăŻäž€ă€ă ă‘ă§ă‹ăŸă„ăŸă›ă‚“ă€‚", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} ăšăźă‚„ă‚Šăšă‚ŠăŒă‚šăƒłăƒ‰ăƒ„ăƒŒă‚šăƒłăƒ‰ă§æš—ć·ćŒ–ă•ă‚ŒăŠă„ă‚‹ă‹ă‚’æ€œèšŒă™ă‚‹ă«ăŻă€ăŠäș’ă„ăźç«Żæœ«ă§ă€äžŠèš˜ăźç•Șć·ăŒç›žæ‰‹ç«Żæœ«äžŠăźç•Șć·ăšćŒă˜ă‹çąșèȘă—ăŠăă ă•ă„ă€‚ç›žæ‰‹ăźç«Żæœ«ă§ă‚ăȘăŸăźă‚łăƒŒăƒ‰ă‚’ă‚čキャンしどもらうæ–čæł•ă‚‚ă‚ă‚ŠăŸă™ă€‚", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "漉慹ç•Șć·ăźć€‰æ›Ž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal ăźăƒ—ăƒ©ă‚€ăƒă‚·ăƒŒæ©Ÿèƒœă‚’ä»„ćŸŒă‚‚æœ‰ćŠčă«ă™ă‚‹ăŸă‚ă«ă€ćź‰ć…šç•Șć·ăŻç§»èĄŒæœŸé–“äž­ă«æ›Žæ–°ă•ă‚ŒăŸă™ă€‚", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "漉慹ç•Șć·ă‚’æ€œèšŒă™ă‚‹ăŸă‚ă«ă€ă‚«ăƒ©ăƒŒă‚«ăƒŒăƒ‰ïŒˆè‰ČăŒă€ă„ăŸæž ć†…ïŒ‰ăźæ•°ć­—ăŒäž€è‡Žă™ă‚‹ă‹ç›žæ‰‹ăźç«Żæœ«ă‚’çąșèȘă—ăŠăă ă•ă„ă€‚æ•°ć­—ăŒäž€è‡Žă—ăȘă„ć ŽćˆăŻă€ćˆ„ăźćź‰ć…šç•Șć·ă‚’èĄšç€șă•ă›ăŠăă ă•ă„ă€‚äž€è‡Žă™ă‚‹æ•°ć­—ăŻäž€ă€ă ă‘ă§ă‹ăŸă„ăŸă›ă‚“ă€‚", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ăŠć›°ă‚Šă§ă™ă‹ïŒŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ă‚ă‹ă‚ŠăŸă—ăŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žäș€æ›ă‚’ă™ă‚‹ăšă€ç›žæ‰‹ăšăźé–“ă«ćź‰ć…šç•Șć·ăŒäœœæˆă•ă‚ŒăŸă™ă€‚", @@ -1267,10 +1359,6 @@ "messageformat": "æœ€èż‘äœżç”šă—ăŸăƒĄăƒ‡ă‚Łă‚ą", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} ăšăźă‚„ă‚Šăšă‚ŠăŒă‚šăƒłăƒ‰ăƒ„ăƒŒă‚šăƒłăƒ‰ă§æš—ć·ćŒ–ă•ă‚ŒăŠă„ă‚‹ă‹ăźćź‰ć…šæ€§ă‚’æ€œèšŒă™ă‚‹ă«ăŻă€ăŠäș’ă„ăźç«Żæœ«ă§ă€äžŠèš˜ăźç•Șć·ăŒç›žæ‰‹ç«Żæœ«äžŠăźç•Șć·ăšćŒă˜ă‹çąșèȘă—ăŠăă ă•ă„ă€‚äžŠéƒšăźQRă‚łăƒŒăƒ‰ă‚’ă‚čキャンするæ–čæł•ă‚‚ă‚ă‚ŠăŸă™ă€‚", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ă“ăźé€Łç”Ąć…ˆăšăŸă ăƒĄăƒƒă‚»ăƒŒă‚žă‚’äș€æ›ă—ăŠă„ăŸă›ă‚“ă€‚ćź‰ć…šç•Șć·ăŻæœ€ćˆăźăƒĄăƒƒă‚»ăƒŒă‚žăźă‚ăšă«ćˆ©ç”šćŻèƒœă«ăȘă‚ŠăŸă™ă€‚" }, @@ -1334,17 +1422,17 @@ "messageformat": "è©łçŽ°", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "æ¶ˆćŽ»", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žă‚’æ¶ˆćŽ»ă™ă‚‹", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ăƒăƒŁăƒƒăƒˆă‚’æ¶ˆćŽ»ă—ăŸă™ă‹ïŒŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žă‚’æ¶ˆćŽ»ă—ăŸă™ă‹ïŒŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ă“ăźăƒăƒŁăƒƒăƒˆăŻă“ăźç«Żæœ«ă‹ă‚‰æ¶ˆćŽ»ă•ă‚ŒăŸă™ă€‚", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ă“ăźăƒăƒŁăƒƒăƒˆć†…ăźăƒĄăƒƒă‚»ăƒŒă‚žăŻă“ăźç«Żæœ«ă‹ă‚‰æ¶ˆćŽ»ă•ă‚ŒăŸă™ă€‚ăƒĄăƒƒă‚»ăƒŒă‚žă‚’æ¶ˆćŽ»ă—ăŸćŸŒă‚‚ă€ă“ăźăƒăƒŁăƒƒăƒˆă‚’æ€œçŽąă§ăăŸă™ă€‚", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ă‚°ăƒ«ăƒŒăƒ—ă‚’é€€ć‡șする", @@ -1438,6 +1526,14 @@ "messageformat": "䞥æ–čăźăƒăƒŁăƒƒăƒˆăźăƒĄăƒƒă‚»ăƒŒă‚žć±„æ­ŽăŻç”±ćˆă•ă‚ŒăŸă—ăŸă€‚", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} は {conversationTitle}ă«æ‰€ć±žă—ăŠă„ăŸă™ă€‚ă‚ăȘたは{sharedGroup}た䞥æ–čăźăƒĄăƒłăƒăƒŒă§ă™ă€‚", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} は {conversationTitle}ă«æ‰€ć±žă—ăŠă„ăŸă™", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ćŒ•ç”šă—ăŸăƒĄăƒƒă‚»ăƒŒă‚žăźç”»ćƒăźă‚”ăƒ ăƒă‚€ăƒ«", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ăƒȘăƒ€ă‚€ăƒ€ăƒ«ă™ă‚‹", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "é€šè©±ă‚’é–‹ć§‹ă™ă‚‹", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "é€šè©±ă«ć‚ćŠ ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "ă™ă§ă«ć€šăăźć‚ćŠ è€…ăŒă„ă‚‹ăŸă‚ăƒžă‚€ă‚Żă‚’ăƒŸăƒ„ăƒŒăƒˆă—ăŸă—ăŸ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ç€äżĄé€šçŸ„", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "æș€ćž­ă§ă™", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ă‚«ăƒĄăƒ©", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "揂抠する", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "開構", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "漚擡ă‚ȘăƒŒăƒăƒŒă§ă™", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ă‚«ăƒĄăƒ©ăŒç„ĄćŠčにăȘăŁăŠă„ăŸă™", @@ -1621,10 +1725,6 @@ "messageformat": "ă‚«ăƒĄăƒ©ă‚’äœżă†", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ăƒŸăƒ„ăƒŒăƒˆ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "ăƒžă‚€ă‚ŻăŒç„ĄćŠčにăȘăŁăŠă„ăŸă™", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ăƒŸăƒ„ăƒŒăƒˆè§Łé™€", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ć…±æœ‰", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ç”»éąăźć…±æœ‰ăŻç„ĄćŠčです", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ç”»éąăźć…±æœ‰ă‚’ćœæ­ąă™ă‚‹", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ć‘Œăłć‡șし", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ă‚°ăƒ«ăƒŒăƒ—ăŒć€§ăă™ăŽă‚‹ăŸă‚ă€ć‚ćŠ è€…ă‚’ć‘ŒăčăŸă›ă‚“ă€‚", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ć‘Œăłć‡șし音を鳮らす", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ć‘Œăłć‡șし音をă‚Șăƒ•ă«ă™ă‚‹", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ć‘Œăłć‡șし音をă‚Șăƒłă«ă™ă‚‹", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ăăźä»–ăźă‚Șăƒ—ă‚·ăƒ§ăƒł", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "あăȘた", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ă‚«ăƒĄăƒ©ăŒă‚Șăƒ•ă«ăȘăŁăŠă„ăŸă™ă€‚", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "漉慹ç•Șć·ăźæ€œèšŒ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€ă‚‹", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "漉慹ç•Șć·ăźæ€œèšŒ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2228,19 +2344,19 @@ "description": "Label for the error toast button" }, "icu:Toast--failed-to-fetch-username": { - "messageformat": "ăƒŠăƒŒă‚¶ćă‚’æ€œçŽąă§ăăŸă›ă‚“ă§ă—ăŸă€‚ă‚€ăƒłă‚żăƒŒăƒăƒƒăƒˆæŽ„ç¶šă‚’çąșèȘă—ăŠć†ćșŠè©Šă—ăŠăă ă•ă„ă€‚", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’æ€œçŽąă§ăăŸă›ă‚“ă§ă—ăŸă€‚ă‚€ăƒłă‚żăƒŒăƒăƒƒăƒˆæŽ„ç¶šă‚’çąșèȘă—ăŠć†ćșŠè©Šă—ăŠăă ă•ă„ă€‚", "description": "Shown if request to Signal servers to find username fails" }, "icu:Toast--failed-to-fetch-phone-number": { "messageformat": "電話ç•Șć·ăźć–ćŸ—ă«ć€±æ•—ă—ăŸă—ăŸă€‚æŽ„ç¶šă‚’çąșèȘă—ăŠć†ćșŠăŠè©Šă—ăă ă•ă„ă€‚", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ç·šé›†ăŻă€ă“ăźăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€äżĄćŸŒ 3 æ™‚é–“ä»„ć†…ăźăżćŻèƒœă§ă™ă€‚", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ç·šé›†ăŻă€ă“ăźăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€äżĄćŸŒ24æ™‚é–“ä»„ć†…ăźăżćŻèƒœă§ă™ă€‚", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { - "messageformat": "ăƒŠăƒŒă‚¶ăŻèŠ‹ă€ă‹ă‚ŠăŸă›ă‚“ă§ă—ăŸă€‚{atUsername} はSignalăƒŠăƒŒă‚¶ă§ăŻă‚ă‚ŠăŸă›ă‚“ă€‚ăƒŠăƒŒă‚¶ćă‚’çąșèȘă—ăŠăă ă•ă„ă€‚", + "messageformat": "ăƒŠăƒŒă‚¶ăŻèŠ‹ă€ă‹ă‚ŠăŸă›ă‚“ă§ă—ăŸă€‚{atUsername} はSignalăƒŠăƒŒă‚¶ă§ăŻă‚ă‚ŠăŸă›ă‚“ă€‚ăƒŠăƒŒă‚¶ăƒŒćă‚’çąșèȘă—ăŠăă ă•ă„ă€‚", "description": "Shown in dialog if username is not found. Note that 'username' will be the output of at-username" }, "icu:startConversation--phone-number-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ă“ăźăƒĄăƒƒă‚»ăƒŒă‚žăŻæ¶ˆćŽ»ă•ă‚ŒăŸă—ăŸă€‚", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "æ·»ä»˜ăƒ•ă‚Ąă‚€ăƒ«ăŒć€§ăă™ăŽăŠèĄšç€șă§ăăŸă›ă‚“ă€‚", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "æ·»ä»˜ăƒ•ă‚Ąă‚€ăƒ«ăŒć€§ăă™ăŽăŠèĄšç€șできăȘă„ă‚‚ăźăŒă‚ă‚ŠăŸă™ă€‚", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ćŻ„ä»˜ăźè©łçŽ°ă‚’ć–ćŸ—ă§ăăŸă›ă‚“", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signalăźăƒ™ăƒŒă‚żç‰ˆă«ăźăżćæ˜ ă•ă‚ŒăŸă™", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žăźç·šé›†ăŻSignalăźăƒ™ăƒŒă‚żç‰ˆăƒŠăƒŒă‚¶ăƒŒăźăżćˆ©ç”šćŻèƒœă§ă™ă€‚ăƒĄăƒƒă‚»ăƒŒă‚žă‚’ç·šé›†ă—ăŸć Žćˆă€Signalăźăƒ™ăƒŒă‚żç‰ˆăźæœ€æ–°ăƒăƒŒă‚žăƒ§ăƒłă‚’ćˆ©ç”šă—ăŠă„ă‚‹äșșă«ăźăżćæ˜ ă•ă‚ŒăŸă™ă€‚", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žăźç·šé›†", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žă‚’ç·šé›†ă—ăŸć Žćˆă€Signalăźæœ€æ–°ăƒăƒŒă‚žăƒ§ăƒłă‚’ćˆ©ç”šă—ăŠă„ă‚‹ăƒŠăƒŒă‚¶ăƒŒă«ăźăżćæ˜ ă•ă‚ŒăŸă™ă€‚ăăźăƒŠăƒŒă‚¶ăƒŒé”ăŻă€ă‚ăȘăŸăŒç·šé›†ă—ăŸăƒĄăƒƒă‚»ăƒŒă‚žă‚’èŠ‹ă‚‹ă“ăšăŒă§ăăŸă™ă€‚", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ビデă‚Șé€šè©±ç€äżĄäž­â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "éŸłćŁ°é€šè©±ç™ș俥", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ビデă‚Ș通話ç™ș俥", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} があăȘăŸă‚’ć‘Œăłć‡șă—ăŠă„ăŸă™", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ć†æŽ„ç¶šă—ăŠă„ăŸă™â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number}äșș}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "éŸłćŁ°é€šè©±", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "甂äș†", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "退ć‡șする", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "ăƒžă‚€ă‚Żă‚Șフ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "ăƒžă‚€ă‚Żă‚Șン", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ć‘Œăłć‡șă—éŸłăŒéłŽăŁăŠă„ăŸă™", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ć‘Œăłć‡șă—éŸłăŒéłŽăŁăŠă„ăŸă›ă‚“", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "èš­ćźš", @@ -3468,13 +3668,25 @@ "messageformat": "ăƒ•ăƒ«ă‚čクăƒȘăƒŒăƒł", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "グăƒȘăƒƒăƒ‰èĄšç€șă«ćˆ‡ă‚Šæ›żăˆă‚‹", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ăƒ“ăƒ„ăƒŒă‚’ćˆ‡ă‚Šæ›żăˆă‚‹", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ă‚čăƒ”ăƒŒă‚«ăƒŒèĄšç€șă«ćˆ‡ă‚Šæ›żăˆă‚‹", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "グăƒȘăƒƒăƒ‰ăƒ“ăƒ„ăƒŒ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ă‚”ă‚€ăƒ‰ăƒăƒŒăƒ“ăƒ„ăƒŒ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ă‚čăƒ”ăƒŒă‚«ăƒŒăƒ“ăƒ„ăƒŒ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ăƒ“ăƒ„ăƒŒăŒæ›Žæ–°ă•ă‚ŒăŸă—ăŸ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "通話甂äș†", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žă‚’ç·šé›†ă§ăăŸă›ă‚“", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚žă‚’ç·šé›†ă§ăă‚‹ăźăŻ{max,number} 曞だけです。", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ごめんăȘさい、sgnl:// ăƒȘăƒłă‚ŻăŻăŸă ă‚”ăƒăƒŒăƒˆă—ăŠă„ăŸă›ă‚“ïŒ", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5249,15 +5469,35 @@ "description": "Default text for about field" }, "icu:ProfileEditor--username": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒć", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă«ć•éĄŒăŒç™șç”Ÿă—ăŸăŸă‚ă€ă‚ąă‚«ă‚Šăƒłăƒˆă«ć‰Čă‚Šćœ“ăŠă‚‰ă‚ŒăŠă„ăŸă›ă‚“ă€‚", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’æ¶ˆćŽ»", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćăźäœœæˆ", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ă‚łăƒŒăƒ‰ă‚‚ă—ăăŻăƒȘンク", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ăƒȘă‚»ăƒƒăƒˆă™ă‚‹ćż…èŠăŒă‚ă‚ŠăŸă™", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăźăƒȘンクをăƒȘă‚»ăƒƒăƒˆă™ă‚‹ćż…èŠăŒă‚ă‚ŠăŸă™", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ć…±æœ‰ă™ă‚‹", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ć…±æœ‰ă™ă‚‹", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" }, "icu:ProfileEditor__username-link__tooltip__body": { @@ -5265,7 +5505,7 @@ "description": "Body of tooltip displayed under 'QR code or link' button for getting username link" }, "icu:ProfileEditor--username--title": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’éžæŠžă—ăŠăă ă•ă„", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’éžæŠžă—ăŠăă ă•ă„", "description": "Title text for username modal" }, "icu:ProfileEditor--username--check-characters": { @@ -5285,7 +5525,7 @@ "description": "Shown if user has attempted to enter a username with too many characters - currently min is 25" }, "icu:ProfileEditor--username--unavailable": { - "messageformat": "ă“ăźăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăŻäœżç”šă§ăăŸă›ă‚“", + "messageformat": "ă“ăźăƒŠăƒŒă‚¶ăƒŒćăŻäœżç”šă§ăăŸă›ă‚“", "description": "Shown if the username is not available for registration" }, "icu:ProfileEditor--username--check-username-taken": { @@ -5297,7 +5537,7 @@ "description": "Shown if something unknown has gone wrong with username save." }, "icu:ProfileEditor--username--reservation-gone": { - "messageformat": "{username} ăŻćˆ©ç”šă§ăăȘくăȘă‚ŠăŸă—ăŸă€‚æ–°ă—ă„æ•°ć­—ăŒăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăšćŻŸă«ăȘă‚ŠăŸă™ă€‚ă‚‚ă†äž€ćșŠäżć­˜ă—ăŠăżăŠăă ă•ă„ă€‚", + "messageformat": "{username} ăŻćˆ©ç”šă§ăăȘくăȘă‚ŠăŸă—ăŸă€‚æ–°ă—ă„æ•°ć­—ăŒăƒŠăƒŒă‚¶ăƒŒćăšćŻŸă«ăȘă‚ŠăŸă™ă€‚ă‚‚ă†äž€ćșŠäżć­˜ă—ăŠăżăŠăă ă•ă„ă€‚", "description": "Shown if username reservation has expired and new one needs to be generated." }, "icu:ProfileEditor--username--delete-general-error": { @@ -5305,7 +5545,7 @@ "description": "Shown if something unknown has gone wrong with username delete." }, "icu:ProfileEditor--username--copied-username": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ă‚łăƒ”ăƒŒă—ăŸă—ăŸ", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ă‚łăƒ”ăƒŒă—ăŸă—ăŸ", "description": "Shown when username is copied to clipboard." }, "icu:ProfileEditor--username--copied-username-link": { @@ -5313,19 +5553,15 @@ "description": "Shown when username link is copied to clipboard." }, "icu:ProfileEditor--username--deleting-username": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ć‰Šé™€ă—ăŠă„ăŸă™", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ć‰Šé™€ă—ăŠă„ăŸă™", "description": "Shown as aria label for spinner icon next to username" }, "icu:ProfileEditor--username--delete-username": { "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’æ¶ˆćŽ»", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ă“ă‚Œă«ă‚ˆă‚Šă€ă‚ăȘăŸăźăƒŠăƒŒă‚¶ăƒŒćăŒć‰Šé™€ă•ă‚Œă€ä»–ăźăƒŠăƒŒă‚¶ăƒŒăŒăăźăƒŠăƒŒă‚¶ăƒŒćă‚’äœżç”šă§ăă‚‹ă‚ˆă†ă«ăȘă‚ŠăŸă™ă€‚ă‚ˆă‚ă—ă„ă§ă™ă‹ïŒŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ć‰Šé™€ă™ă‚‹ăšă€QR ă‚łăƒŒăƒ‰ăšăƒȘンクが無ćŠčにăȘă‚ŠăŸă™ă€‚ă€Œ{username}ă€ăŻä»–ăźăƒŠăƒŒă‚¶ăƒŒă«äœżç”šćŻèƒœăšăȘă‚ŠăŸă™ă€‚æœŹćœ“ă«ć‰Šé™€ă—ăŸă™ă‹ïŒŸ", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ć‰Šé™€ă™ă‚‹ăšă€QR ă‚łăƒŒăƒ‰ăšăƒȘンクが無ćŠčにăȘă‚ŠăŸă™ă€‚ă€Œ{username}ă€ăŻä»–ăźăƒŠăƒŒă‚¶ăƒŒă«äœżç”šćŻèƒœăšăȘă‚ŠăŸă™ă€‚æœŹćœ“ă«ć‰Šé™€ă—ăŸă™ă‹ïŒŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" }, "icu:ProfileEditor--username--confirm-delete-button": { @@ -5333,11 +5569,11 @@ "description": "Shown in dialog button if user has saved an empty string to delete their username" }, "icu:ProfileEditor--username--context-menu": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ă‚łăƒ”ăƒŒăŸăŸăŻæ¶ˆćŽ»ă—ăŸă™", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ă‚łăƒ”ăƒŒăŸăŸăŻæ¶ˆćŽ»ă—ăŸă™", "description": "Shown as aria label for context menu next to username" }, "icu:ProfileEditor--username--copy": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ă‚łăƒ”ăƒŒă—ăŸă™", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ă‚łăƒ”ăƒŒă—ăŸă™", "description": "Shown as a button in context menu next to username. The action of the button is to put username into the clipboard." }, "icu:ProfileEditor--username--copy-link": { @@ -5405,7 +5641,7 @@ "description": "Title for profile avatar editing" }, "icu:ProfileEditorModal--username": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒć", "description": "Title for username editing" }, "icu:ProfileEditorModal--error": { @@ -5612,6 +5848,42 @@ "messageformat": "ă‚čăƒˆăƒŒăƒȘăƒŒă‚’ć…±æœ‰ă—ăŸă‚Šé–ČèŠ§ă—ăŸă‚Šă§ăăȘくăȘă‚ŠăŸă™ă€‚æœ€èż‘ć…±æœ‰ă—ăŸă‚čăƒˆăƒŒăƒȘăƒŒăźæ›Žæ–°æƒ…ć ±ă‚‚æ¶ˆćŽ»ă•ă‚ŒăŸă™ă€‚", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "蚀èȘž", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "蚀èȘž", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ă‚·ă‚čăƒ†ăƒ èš€èȘž", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "蚀èȘžăźæ€œçŽą", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” ăźæ€œçŽąç”æžœăŻă‚ă‚ŠăŸă›ă‚“", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "èš­ćźšă™ă‚‹", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "適甚するにはSignală‚’ć†è”·ć‹•ă—ăŸă™", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "蚀èȘžă‚’ć€‰æ›Žă™ă‚‹ă«ăŻă€ă‚ąăƒ—ăƒȘă‚’ć†è”·ć‹•ă™ă‚‹ćż…èŠăŒă‚ă‚ŠăŸă™ă€‚", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ć†è”·ć‹•", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ăƒăƒŒă‚žăƒ§ăƒł{version}ăžăźă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆăŒă‚ă‚ŠăŸă™", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "èš­ćźšăźäżć­˜æ™‚ă«ă‚šăƒ©ăƒŒăŒç™șç”Ÿă—ăŸă—ăŸă€‚ć†ćșŠè©Šă—ăŠăă ă•ă„ă€‚", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ăƒĄăƒƒă‚»ăƒŒă‚ž", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ăăźä»–ăźă‚čă‚żă‚€ăƒ«", "description": "Action button for switching up the clock styles" @@ -6485,11 +6761,11 @@ "description": "Default aria-label for the context menu buttons" }, "icu:EditUsernameModalBody__username-placeholder": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒć", "description": "Placeholder for the username field" }, "icu:EditUsernameModalBody__username-helper": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’äœżç”šă™ă‚‹ăšă€ç›žæ‰‹ăŻé›»è©±ç•Șć·ăȘしであăȘăŸă«ăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€ă‚ŒăŸă™ă€‚ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăŻæ•°ć­—ăšćŻŸă«ăȘっどいるぼでケドレă‚čă‚’éžć…Źé–‹ă«ă™ă‚‹ă“ăšăŒă§ăăŸă™ă€‚", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’äœżç”šă™ă‚‹ăšă€ç›žæ‰‹ăŻé›»è©±ç•Șć·ăȘしであăȘăŸă«ăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€ă‚ŒăŸă™ă€‚ăƒŠăƒŒă‚¶ăƒŒćăŻæ•°ć­—ăšćŻŸă«ăȘっどいるぼでケドレă‚čă‚’éžć…Źé–‹ă«ă™ă‚‹ă“ăšăŒă§ăăŸă™ă€‚", "description": "Shown on the edit username screen" }, "icu:EditUsernameModalBody__learn-more": { @@ -6501,11 +6777,11 @@ "description": "Title of the popup with information about discriminator in username" }, "icu:EditUsernameModalBody__learn-more__body": { - "messageformat": "ă“ă‚Œă‚‰ăźæ•°ć­—ăŻă€ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’éžć…Źé–‹ă«ă—ă€äžèŠăȘăƒĄăƒƒă‚»ăƒŒă‚žă‚’éżă‘ă‚‹ăźă«ćœčç«‹ăĄăŸă™ă€‚ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăŻă€ăƒăƒŁăƒƒăƒˆă‚’ă—ăŸă„äșșă‚„ă‚°ăƒ«ăƒŒăƒ—ăšă ă‘ć…±æœ‰ă—ăŠăă ă•ă„ă€‚ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ć€‰æ›Žă™ă‚‹ăšă€æ–°ă—ă„æ•°ć­—ă«æ›Žæ–°ă•ă‚ŒăŸă™ă€‚", + "messageformat": "ă“ă‚Œă‚‰ăźæ•°ć­—ăŻă€ăƒŠăƒŒă‚¶ăƒŒćă‚’éžć…Źé–‹ă«ă—ă€äžèŠăȘăƒĄăƒƒă‚»ăƒŒă‚žă‚’éżă‘ă‚‹ăźă«ćœčç«‹ăĄăŸă™ă€‚ăƒŠăƒŒă‚¶ăƒŒćăŻă€ăƒăƒŁăƒƒăƒˆă‚’ă—ăŸă„äșșă‚„ă‚°ăƒ«ăƒŒăƒ—ăšă ă‘ć…±æœ‰ă—ăŠăă ă•ă„ă€‚ăƒŠăƒŒă‚¶ăƒŒćă‚’ć€‰æ›Žă™ă‚‹ăšă€æ–°ă—ă„æ•°ć­—ă«æ›Žæ–°ă•ă‚ŒăŸă™ă€‚", "description": "Body of the popup with information about discriminator in username" }, "icu:EditUsernameModalBody__change-confirmation": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’ć€‰æ›Žă™ă‚‹ăšă€ă“ă‚ŒăŸă§ăźQRă‚łăƒŒăƒ‰ăšăƒȘンクがăƒȘă‚»ăƒƒăƒˆă•ă‚ŒăŸă™ă€‚æœŹćœ“ă«ć€‰æ›Žă—ăŸă™ă‹ïŒŸ", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćă‚’ć€‰æ›Žă™ă‚‹ăšă€ă“ă‚ŒăŸă§ăźQRă‚łăƒŒăƒ‰ăšăƒȘンクがăƒȘă‚»ăƒƒăƒˆă•ă‚ŒăŸă™ă€‚æœŹćœ“ă«ć€‰æ›Žă—ăŸă™ă‹ïŒŸ", "description": "Body of the confirmation dialog displayed when user is about to change their username" }, "icu:EditUsernameModalBody__change-confirmation__continue": { @@ -6525,35 +6801,47 @@ "description": "ARIA label of the button for copying the username link to clipboard in the username link modal" }, "icu:UsernameLinkModalBody__help": { - "messageformat": "QR ă‚łăƒŒăƒ‰ăšăƒȘăƒłă‚ŻăŻă€äżĄé Œă§ăă‚‹äșșăšăźăżć…±æœ‰ă—ăŠăă ă•ă„ă€‚ć…±æœ‰ă™ă‚‹ăšă€ç›žæ‰‹ăŻă‚ăȘăŸăźăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’èŠ‹ăŸă‚ŠăƒăƒŁăƒƒăƒˆă‚’ă—ăŸă‚Šă§ăă‚‹ă‚ˆă†ă«ăȘă‚ŠăŸă™ă€‚", + "messageformat": "QR ă‚łăƒŒăƒ‰ăšăƒȘăƒłă‚ŻăŻă€äżĄé Œă§ăă‚‹äșșăšăźăżć…±æœ‰ă—ăŠăă ă•ă„ă€‚ć…±æœ‰ă™ă‚‹ăšă€ç›žæ‰‹ăŻă‚ăȘăŸăźăƒŠăƒŒă‚¶ăƒŒćă‚’èŠ‹ăŸă‚ŠăƒăƒŁăƒƒăƒˆă‚’ă—ăŸă‚Šă§ăă‚‹ă‚ˆă†ă«ăȘă‚ŠăŸă™ă€‚", "description": "Text of disclaimer at the bottom of the username link modal" }, "icu:UsernameLinkModalBody__reset": { "messageformat": "ăƒȘă‚»ăƒƒăƒˆă™ă‚‹", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "漌äș†", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăźăƒȘンクぼè‰Č {index,number}/{total,number}", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćăźăƒȘンクぼè‰Č {index,number}/{total,number}", "description": "ARIA label of button for selecting username link color" }, "icu:UsernameLinkModalBody__reset__confirm": { "messageformat": "QRă‚łăƒŒăƒ‰ă‚’ăƒȘă‚»ăƒƒăƒˆă™ă‚‹ăšă€ă“ă‚ŒăŸă§ăźQRă‚łăƒŒăƒ‰ăšăƒȘンクは無ćŠčにăȘă‚ŠăŸă™ă€‚", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ăƒȘンクをăƒȘă‚»ăƒƒăƒˆă—ăŠă„ăŸă™...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QRă‚łăƒŒăƒ‰ăŠă‚ˆăłăƒȘăƒłă‚ŻăŒèš­ćźšă•ă‚ŒăŠă„ăŸă›ă‚“ă€‚ăƒăƒƒăƒˆăƒŻăƒŒă‚ŻæŽ„ç¶šă‚’çąșèȘă—ăŠć†ćșŠè©Šă—ăŠăă ă•ă„ă€‚", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { - "messageformat": "SignalăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă‚’èš­ćźšă™ă‚‹", + "messageformat": "SignalăƒŠăƒŒă‚¶ăƒŒćă‚’èš­ćźšă™ă‚‹", "description": "Title of username onboarding modal" }, "icu:UsernameOnboardingModalBody__row__number": { - "messageformat": "ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăŻæ•°ć­—ăšćŻŸă«ăȘăŁăŠăŠă‚Šă€ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ă§ć…±æœ‰ă•ă‚Œă‚‹ă“ăšăŻă‚ă‚ŠăŸă›ă‚“", + "messageformat": "ăƒŠăƒŒă‚¶ăƒŒćăŻæ•°ć­—ăšćŻŸă«ăȘăŁăŠăŠă‚Šă€ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ă§ć…±æœ‰ă•ă‚Œă‚‹ă“ăšăŻă‚ă‚ŠăŸă›ă‚“", "description": "Content of the first row of username onboarding modal" }, "icu:UsernameOnboardingModalBody__row__link": { - "messageformat": "ć„ăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ă«ăŻć›șæœ‰ăź QR ă‚łăƒŒăƒ‰ăšăƒȘăƒłă‚ŻăŒă‚ă‚Šă€ć‹é”ăšć…±æœ‰ă™ă‚‹ă“ăšă§ăƒăƒŁăƒƒăƒˆă‚’é–‹ć§‹ă™ă‚‹ă“ăšăŒă§ăăŸă™", + "messageformat": "ć„ăƒŠăƒŒă‚¶ăƒŒćă«ăŻć›șæœ‰ăź QR ă‚łăƒŒăƒ‰ăšăƒȘăƒłă‚ŻăŒă‚ă‚Šă€ć‹é”ăšć…±æœ‰ă™ă‚‹ă“ăšă§ăƒăƒŁăƒƒăƒˆă‚’é–‹ć§‹ă™ă‚‹ă“ăšăŒă§ăăŸă™", "description": "Content of the second row of username onboarding modal" }, "icu:UsernameOnboardingModalBody__row__lock": { - "messageformat": "èš­ćźš > ăƒ—ăƒ©ă‚€ăƒă‚·ăƒŒ > 電話ç•Șć· >ă€Œé›»è©±ç•Șć·ă§ăźæ€œçŽąă‚’ćŻèƒœă«ă™ă‚‹ă€ă§é›»è©±ç•Șć·æ€œçŽąă‚’ă‚Șăƒ•ă«ă™ă‚‹ăšă€ä»–ăźăƒŠăƒŒă‚¶ăƒŒă‹ă‚‰ă‚ăȘたまぼćŸșæœŹăźé€Łç”Ąæ–čæł•ăŻăƒŠăƒŒă‚¶ăƒŒăƒăƒŒăƒ ăźäœżç”šăšăȘă‚ŠăŸă™ă€‚", + "messageformat": "èš­ćźš > ăƒ—ăƒ©ă‚€ăƒă‚·ăƒŒ > 電話ç•Șć· >ă€Œé›»è©±ç•Șć·ă§ăźæ€œçŽąă‚’ćŻèƒœă«ă™ă‚‹ă€ă§é›»è©±ç•Șć·æ€œçŽąă‚’ă‚Șăƒ•ă«ă™ă‚‹ăšă€ä»–ăźăƒŠăƒŒă‚¶ăƒŒă‹ă‚‰ă‚ăȘたまぼćŸșæœŹăźé€Łç”Ąæ–čæł•ăŻăƒŠăƒŒă‚¶ăƒŒćăźäœżç”šăšăȘă‚ŠăŸă™ă€‚", "description": "Content of the third row of username onboarding modal" }, "icu:UsernameOnboardingModalBody__learn-more": { @@ -6592,6 +6880,114 @@ "messageformat": "憍送", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ăăźä»–", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "通話", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "é€šè©±ă™ă‚‹", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "é€šè©±ă™ă‚‹", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ăăźä»–", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "é€šè©±ć±„æ­Žă‚’æ¶ˆćŽ»ă™ă‚‹", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "é€šè©±ć±„æ­Žă‚’æ¶ˆćŽ»ă—ăŸă™ă‹ïŒŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "すăčăŠăźé€šè©±ć±„æ­Žă‚’ćźŒć…šă«æ¶ˆćŽ»ă—ăŸă™", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "æ¶ˆćŽ»ă™ă‚‹", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "é€šè©±ć±„æ­ŽăŒă‚ŻăƒȘă‚ąă•ă‚ŒăŸă—ăŸ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "クăƒȘăƒƒă‚Żă—ăŠé€šè©±ă‚’èĄšç€șă€ăŸăŸăŻé€šè©±ă‚’é–‹ć§‹ă—ăŸă™", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "æ€œçŽą", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "äžćœšç€äżĄă§ăƒ•ă‚Łăƒ«ă‚żăƒȘングする", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ćˆ‡ă‚Šæ›żăˆ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "æœ€èż‘ăźé€šè©±ăŻă‚ă‚ŠăŸă›ă‚“ă€‚ ć‹é”ă«é›»è©±ă‚’ă‹ă‘ăŸă—ă‚‡ă†ă€‚", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” ăźæ€œçŽąç”æžœăŻă‚ă‚ŠăŸă›ă‚“", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "着信", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ç™ș俥", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "侍朹着信", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ă‚°ăƒ«ăƒŒăƒ—é€šè©±", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "æœ€èż‘ăźé€šè©±ăŻă‚ă‚ŠăŸă›ă‚“ă€‚", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” ăźæ€œçŽąç”æžœăŻă‚ă‚ŠăŸă›ă‚“", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {éŸłćŁ°é€šè©±ç™ș俥} other {éŸłćŁ°é€šè©±ç€äżĄ}}} Video {{direction, select, Outgoing {ビデă‚Ș通話ç™ș俥} other {ビデă‚Șé€šè©±ç€äżĄ}}} Group {{direction, select, Outgoing {ă‚°ăƒ«ăƒŒăƒ—é€šè©±ç™ș俥} other {ă‚°ăƒ«ăƒŒăƒ—é€šè©±ç€äżĄ}}} other {{direction, select, Outgoing {ç™ș俥} other {着信}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {éŸłćŁ°é€šè©±ç€äżĄă‚ă‚Š} Video {ビデă‚Șé€šè©±ç€äżĄă‚ă‚Š} Group {ă‚°ăƒ«ăƒŒăƒ—é€šè©±ç€äżĄă‚ă‚Š} other {侍朹着信}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {éŸłćŁ°é€šè©±ćżœç­”ăȘし} Video {ビデă‚Șé€šè©±ćżœç­”ăȘし} Group {ă‚°ăƒ«ăƒŒăƒ—é€šè©±ă«ćżœç­”ăŒă‚ă‚ŠăŸă›ă‚“ă§ă—ăŸ} other {éŸłćŁ°é€šè©±ă«ćżœç­”ăŒă‚ă‚ŠăŸă›ă‚“ă§ă—ăŸ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {éŸłćŁ°é€šè©±ăŒæ‹’ćŠă•ă‚ŒăŸă—ăŸ} Video {ビデă‚Șé€šè©±ăŒæ‹’ćŠă•ă‚ŒăŸă—ăŸ} Group {ă‚°ăƒ«ăƒŒăƒ—é€šè©±ăŒæ‹’ćŠă•ă‚ŒăŸă—ăŸ} other {ビデă‚Șé€šè©±ăŒæ‹’ćŠă•ă‚ŒăŸă—ăŸ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number} äșșăŒć…„ćŠ›äž­ă§ă™ă€‚}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "æ›Žæ–°æƒ…ć ±", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "箰かăȘćŸźèȘżæ•Žă€ăƒă‚°äżźæ­Łă€ăƒ‘ăƒ•ă‚©ăƒŒăƒžăƒłă‚čぼ搑侊。 Signală‚’ă”ćˆ©ç”šă„ăŸă ăă‚ă‚ŠăŒăšă†ă”ă–ă„ăŸă™ă€‚", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ă“ăźă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆă§ăŻă€éŸłćŁ°é€šè©±ăšăƒ“ăƒ‡ă‚Șé€šè©±ă«é–ąă™ă‚‹è€‡æ•°ăźæ”čć–„ăšăƒ‰ă‚­ăƒ„ăƒĄăƒłăƒˆăźäž€éƒšăźæ›Žæ–°ăŒăŠă“ăȘă‚ă‚ŒăŸă—ăŸïŒˆă‚ă‚ŠăŒăšă†ă€ {linkToGithub}" + "icu:WhatsNew__v6.39--0": { + "messageformat": "ă‚·ă‚čăƒ†ăƒ èš­ćźšă‚’ć€‰æ›Žă™ă‚‹ă“ăšăȘく、Signală§éžæŠžă—ăŸèš€èȘžă‚’ć€‰æ›Žă§ăă‚‹ă‚ˆă†ă«ăȘă‚ŠăŸă—ăŸïŒˆSignalăźèš­ćźš > ăƒ‡ă‚¶ă‚€ăƒł > 蚀èȘžïŒ‰ă€‚" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ă‚°ăƒ«ăƒŒăƒ—é€šçŸ„ă‚ąă‚€ă‚łăƒłă‚’ă„ăă€ă‹æ›Žæ–°ă—ăŸă—ăŸă€‚" + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOSă§é€šè©±ăƒ­ăƒ“ăƒŒă«ć‚ćŠ ă—ăŸéš›ă«ă€ă‚ăšă‹ăȘ遅れがç™șç”Ÿă™ă‚‹ă“ăšăŒă‚ăŁăŸć•éĄŒă‚’è§Łæ¶ˆă—ăŸă—ăŸă€‚" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "èȘ°ă‹ăŒă‚°ăƒ«ăƒŒăƒ—é€šè©±ă«ć‚ćŠ ăŸăŸăŻé€€ć‡șă™ă‚‹éš›ăźç”»éąèĄšç€șăźćˆ‡ă‚Šæ›żăˆă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚’äżźæ­Łă—ăŸă—ăŸă€‚" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ăƒăƒŁăƒƒăƒˆăźăƒ˜ăƒƒăƒ€ăƒŒă«ă‚ă‚‹ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ć†™çœŸă‚„ă‚°ăƒ«ăƒŒăƒ—ă‚ąăƒă‚żăƒŒă‚’ă‚ŻăƒȘăƒƒă‚Żă™ă‚‹ăšă€ăăźăƒăƒŁăƒƒăƒˆăźèš­ćźšă«çŽ æ—©ăă‚ąă‚Żă‚»ă‚čしたり、è©Čćœ“ăƒăƒŁăƒƒăƒˆăźèŠ‹é€ƒă—ăŠă„ăŸă‚čăƒˆăƒŒăƒȘăƒŒă‚’èĄšç€șă—ăŸă‚Šă§ăă‚‹ă‚ˆă†ă«ăȘă‚ŠăŸă—ăŸă€‚ă‚ă‚ŠăŒăšă†ă€{linkToGithub}" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ka-GE/messages.json b/_locales/ka-GE/messages.json index bab42bdda4..af3beef5dd 100644 --- a/_locales/ka-GE/messages.json +++ b/_locales/ka-GE/messages.json @@ -41,7 +41,7 @@ "description": "Shown in the affirmative button of the confirmation dialog when adding a contact to a group" }, "icu:AddUserToAnotherGroupModal__confirm-message": { - "messageformat": "\"{contact}\"-იქ დამაჱება \"{group}\"-ლი", + "messageformat": "\"{contact}\"-იქ დამაჱება áƒŻáƒ’áƒŁáƒ€áƒšáƒ˜ \"{group}\"", "description": "Shown in the confirmation dialog body when adding a contact to a group" }, "icu:AddUserToAnotherGroupModal__toast--user-added-to-group": { @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "მონაáƒȘემთა ბაზის ჼარვეზი", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "მონაáƒȘემთა ბაზის ჼარვეზს გადავაწყდით. ლეგიძლია ჹეáƒȘდომა დააკოპირო და Signal-იქ მჼარდაჭერის გუნდს დაუკავჹირდე, რათა პრობლემის მოგვარებაჹი დაგეჼმაროთ. თუ Signal-იქ გამოყენება დაუყოვნებლივ გჭირდება, ლეგიძლია ჹენი მონაáƒȘემები წაჹალო და გადაჱვირთო.\n\nდაუკავჹირდი მჼარდაჭერის გუნდს: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "მონაáƒȘემების სრულად წაჹლა და თავიდან დაწყება", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "მონაáƒȘემთა წაჹლა და გადაჱვირთვა", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "გსურს სამუდამოდ წაჹალო ყველა მონაáƒȘემი?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ჹენი მიმოწერის მთელი ისჱორია და მედია Ⴠაილები ამ მოწყობილობიდან სამუდამოდ წაიჹლება. Signal-იქ გამოყენებას ამ მოწყობილობაზე ჼელაჼლა დაკავჹირების ჹემდეგ ლეძლებ. ეს ჹენი áƒąáƒ”áƒšáƒ”áƒ€áƒáƒœáƒ˜áƒ“áƒáƒœ არáƒȘერთ მონაáƒȘემს არ წაჹლის.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "ჹენი მონაáƒȘემთა ბაზის ვერსია Signal-იქ ამ ვერსიას არ ემთჼვევა. დარწმუნდი, რომ ჹენს კომპიუჱერჹი Signal-იქ უაჼლეს ვერსიას ჼსნი.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Ⴠაილი", @@ -300,6 +316,70 @@ "messageformat": "áƒ©áƒáƒąáƒ”áƒ‘áƒ˜", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ჹენს მომჼმარებლის საჼელს რა჊აáƒȘ მოუვიდა, იქ ჹენს მონაáƒȘემებთან ა჊არ არიქ დაკავჹირებული. ლეგიძლია ქáƒȘადო და იქ აჼლიდან დააყენო, ან აჼალი ლეარჩიო.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "აჼლა მოგვარება", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ჹენს QR კოდსა და მომჼმარებლის საჼელის ბმულთან დაკავჹირებით რა჊აáƒȘ ჹეáƒȘდომა მოჼდა, იქ ა჊არ არიქ მოჄმედი. ლეჄმენი აჼალი ბმული სჼვებისთვის გასაზიარებლად.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "აჼლა მოგვარება", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "áƒ©áƒáƒœáƒáƒ áƒ—áƒ”áƒ‘áƒ˜áƒĄ გამოჩენა", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "áƒ©áƒáƒœáƒáƒ áƒ—áƒ”áƒ‘áƒ˜áƒĄ დამალვა", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "მოჼდა ჼარვეზი", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} წაუკითჼავი", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "მონიჹნულია წაუკითჼავად", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "áƒ©áƒáƒąáƒ”áƒ‘áƒ˜", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ზარები", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories-ები", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "პარამეჱრები", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal-იქ განაჼლება", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "პროჀილი", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "უკან", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ეს áƒ©áƒáƒąáƒ”áƒ‘áƒ˜ áƒ“áƒáƒáƒ áƒ„áƒ˜áƒ•áƒ”áƒ‘áƒŁáƒšáƒ˜áƒ და ჹემომავალ ჹეჱყობინებებჹი მჼოლოდ აჼალი ჹეჱყობინებების მიჩების ჹემთჼვევაჹი გამოჩნდება.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -349,7 +429,7 @@ "description": "Shown as the title in the confirmation modal for removing a contact from the contact list" }, "icu:ContactListItem__remove--body": { - "messageformat": "áƒ«áƒ”áƒ‘áƒœáƒ˜áƒĄáƒáƒĄ ამ ადამიანს ვერ ნაჼავ. თუ მომავალჹი მოგწერს, ჹეჱყობინების მოთჼოვნას მიიჩებ.", + "messageformat": "áƒ«áƒ”áƒ‘áƒœáƒ˜áƒĄáƒáƒĄ ამ ადამიანს ვერ ნაჼავ. თუ მომავალჹი ჹეჱყობინებას გამოგიგზავნის, მიმოწერის მოთჼოვნას მიიჩებ.", "description": "Shown as the body in the confirmation modal for removing a contact from the contact list" }, "icu:ContactListItem__remove--confirm": { @@ -381,7 +461,7 @@ "description": "Shown in a toast when a user attempts to pin more than the maximum number of chats" }, "icu:chooseDirectory": { - "messageformat": "Choose folder", + "messageformat": "აირჩიე ჹენაჼვის ადგილი", "description": "Button to allow the user to find a folder on disk" }, "icu:chooseFile": { @@ -401,7 +481,7 @@ "description": "Title of the popup window used to select data previously exported" }, "icu:importErrorHeader": { - "messageformat": "Something went wrong!", + "messageformat": "áȠა჊აáƒȘ არასწორად წავიდა!", "description": "Header of the error screen after a failed import" }, "icu:importingHeader": { @@ -409,7 +489,7 @@ "description": "Header of screen shown as data is import" }, "icu:importErrorFirst": { - "messageformat": "დარწმუნდი, რომ სწორი კაჱალოგი აირჩიე, რომელიáƒȘ ჹეიáƒȘავს ჹენი Signal-იქ ჹენაჼულ მონაáƒȘემებს. მისი საჼელი უნდა იწყებოდეს „Signal-იქ áƒ”áƒ„áƒĄáƒžáƒáƒ áƒąáƒ˜â€œ. ასევე ლეგიძლია ჹენი მონაáƒȘემების აჼალი კოპია Chrome-იქ აპიდან ჹეინაჼო.", + "messageformat": "დარწმუნდი, რომ სწორი კაჱალოგი აირჩიე, რომელიáƒȘ ჹეიáƒȘავს ჹენი Signal-იქ ჹენაჼულ მონაáƒȘემებს. მისი საჼელი უნდა იწყებოდეს 'Signal Export.' ასევე ლეგიძლია ჹენი მონაáƒȘემების აჼალი კოპია Chrome-იქ აპიდან ჹეინაჼო.", "description": "Message shown if the import went wrong; first paragraph" }, "icu:importErrorSecond": { @@ -417,11 +497,11 @@ "description": "Message shown if the import went wrong; second paragraph" }, "icu:importAgain": { - "messageformat": "Choose folder and try again", + "messageformat": "აირჩიე ჹენაჼვის ადგილი და ქáƒȘადე ჼელაჼლა", "description": "Button shown if the user runs into an error during import, allowing them to start over" }, "icu:importCompleteHeader": { - "messageformat": "Success!", + "messageformat": "წარმაჱებულია!", "description": "Header shown on the screen at the end of a successful import process" }, "icu:importCompleteStartButton": { @@ -433,7 +513,7 @@ "description": "Button shown at end of successful 'light' import process, so the standard linking process still needs to happen" }, "icu:selectedLocation": { - "messageformat": "your selected location", + "messageformat": "ჹენ მიერ áƒáƒ áƒ©áƒ”áƒŁáƒšáƒ˜ მდებარეობა", "description": "Message shown as the export location if we didn't capture the target directory" }, "icu:upgradingDatabase": { @@ -441,15 +521,15 @@ "description": "Message shown on the loading screen when we're changing database structure on first run of a new version" }, "icu:loadingMessages--other": { - "messageformat": "{daysAgo, plural, one {იჱვირთება 1 დჩის წინანდელი წერილები...} other {იჱვირთება {daysAgo,number} დჩის წინანდელი წერილები...}}", + "messageformat": "{daysAgo, plural, one {იჱვირთება 1 დჩის წინანდელი ჹეჱყობინებები...} other {იჱვირთება {daysAgo,number} დჩის წინანდელი ჹეჱყობინებები...}}", "description": "Message shown on the loading screen when we're catching up on the backlog of messages from day before yesterday and earlier" }, "icu:loadingMessages--yesterday": { - "messageformat": "იჱვირთება გუჹინდელი წერილები...", + "messageformat": "იჱვირთება გუჹინდელი ჹეჱყობინებები...", "description": "Message shown on the loading screen when we're catching up on the backlog of messages from yesterday" }, "icu:loadingMessages--today": { - "messageformat": "იჱვირთება დჩევანდელი წერილები...", + "messageformat": "იჱვირთება დჩევანდელი ჹეჱყობინებები...", "description": "Message shown on the loading screen when we're catching up on the backlog of messages from today" }, "icu:view": { @@ -469,7 +549,7 @@ "description": "Alt text for button to take user down to bottom of conversation, shown when user scrolls up" }, "icu:messagesBelow": { - "messageformat": "New messages below", + "messageformat": "აჼალი ჹეჱყობინებები Ⴤვემოთ", "description": "Alt text for button to take user down to bottom of conversation with more than one message out of screen" }, "icu:mentionsBelow": { @@ -477,7 +557,7 @@ "description": "Alt text for button to take user down to next mention of them further down the message list (currently out of screen)" }, "icu:unreadMessage": { - "messageformat": "1 Unread Message", + "messageformat": "1 წაუკითჼავი ჹეჱყობინება", "description": "Text for unread message separator, just one message" }, "icu:unreadMessages": { @@ -489,27 +569,27 @@ "description": "Shown in the conversation history when a user links a new device to explain what is not supported." }, "icu:youMarkedAsVerified": { - "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-ი ვერიჀიáƒȘირებულად მონიჹნე", + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-სთან ვერიჀიáƒȘირებულად მონიჹნე", "description": "Shown in the conversation history when the user marks a contact as verified." }, "icu:youMarkedAsNotVerified": { - "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-ი არა-ვერიჀიáƒȘირებულად მონიჹნე", + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-სთან არა-ვერიჀიáƒȘირებულად მონიჹნე", "description": "Shown in the conversation history when the user marks a contact as not verified, whether on the Safety Number screen or by dismissing a banner or dialog." }, "icu:youMarkedAsVerifiedOtherDevice": { - "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი{name}-ი ვერიჀიáƒȘირებულად მონიჹნე სჼვა მოწყობილობიდან", + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი{name}-სთან ვერიჀიáƒȘირებულად მონიჹნე სჼვა მოწყობილობიდან", "description": "Shown in the conversation history when we discover that the user marked a contact as verified on another device." }, "icu:youMarkedAsNotVerifiedOtherDevice": { - "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-ი არა-ვერიჀიáƒȘირებულად მონიჹნე სჼვა მოწყობილობიდან", + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-სთან არა-ვერიჀიáƒȘირებულად მონიჹნე სჼვა მოწყობილობიდან", "description": "Shown in the conversation history when we discover that the user marked a contact as not verified on another device." }, "icu:membersNeedingVerification": { - "messageformat": "Your safety numbers with these group members have changed since you last verified. Click a group member to see your new safety number with them.", + "messageformat": "ჹეენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრები ამ áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ წევრებთან ჹეიáƒȘვალა მას ჹემდეგ, რაáƒȘ ბოლოს დაადასჱურე. დააწკაპუნე áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ წევრზე, რომ დაინაჼო ჹენი აჼალი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი მასთან ერთად.", "description": "When there are multiple previously-verified group members with safety number changes, a banner will be shown. The list of contacts with safety number changes is shown, and this text introduces that list." }, "icu:changedRightAfterVerify": { - "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი, რომლის ვერიჀიáƒȘირებასაáƒȘ áƒȘდილობ, ჹეიáƒȘვალა. გთჼოვთ, გადაჼედო {name1}-იქ აჼალ áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერს. დაიმაჼსოვრე, ეს áƒȘვლილება ლეიძლება ნიჹნავს, რომ ვიჩაáƒȘ áƒȘდილობს ჹენს კომუნიკაáƒȘიალი ჹემოწრას ან რომ {name2}-მა უბრალოდ გადააყენა Signal-ი.", + "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი, რომლის ვერიჀიáƒȘირებასაáƒȘ áƒȘდილობ, ჹეიáƒȘვალა. გთჼოვთ, გადაჼედო {name1}-იქ აჼალ áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერს. დაიმაჼსოვრე, ეს áƒȘვლილება ლეიძლება ნიჹნავს, რომ ვიჩაáƒȘ áƒȘდილობს ჹენს კომუნიკაáƒȘიალი ჹემოჭრას ან რომ {name2}-მა უბრალოდ გადააყენა Signal-ი.", "description": "Shown on the safety number screen when the user has selected to verify/unverify a contact's safety number, and we immediately discover a safety number change" }, "icu:safetyNumberChangeDialog__message": { @@ -557,7 +637,7 @@ "description": "Label for button that opens context menu for story" }, "icu:identityKeyErrorOnSend": { - "messageformat": "{name1}-იქ ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი ჹეიáƒȘვალა. ეს ლეიძლება ნიჹნავდეს, რომ ვიჩაáƒȘ áƒȘდილობს ჹენს კომუნიკაáƒȘიალი ჹეჭრას ან რომ {name2}-მა უბრალოდ გადააყენა Signal-ი. ჹენ ლეგიძლია დაადასჱურო ამ áƒ™áƒáƒœáƒąáƒáƒ„áƒąáƒ—áƒáƒœ არსებული áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი.", + "messageformat": "{name1}-სთან ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი ჹეიáƒȘვალა. ეს ლეიძლება ნიჹნავდეს, რომ ვიჩაáƒȘ áƒȘდილობს ჹენს კომუნიკაáƒȘიალი ჹეჭრას ან რომ {name2}-მა უბრალოდ გადააყენა Signal-ი. ჹენ ლეგიძლია დაადასჱურო ამ áƒ™áƒáƒœáƒąáƒáƒ„áƒąáƒ—áƒáƒœ არსებული áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი.", "description": "Shown when user clicks on a failed recipient in the message detail view after an identity key change" }, "icu:sendAnyway": { @@ -576,16 +656,20 @@ "messageformat": "მაინáƒȘ დარეკვა", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "მაინáƒȘ ჹესვლა", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ზარის გაგრძელება", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." }, "icu:noLongerVerified": { - "messageformat": "Your safety number with {name} has changed and is no longer verified. Click to show.", + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-სთან ჹეიáƒȘვალა და ა჊არ არიქ ვერიჀიáƒȘირებული. დააწკაპუნე áƒĄáƒáƒ©áƒ•áƒ”áƒœáƒ”áƒ‘áƒšáƒáƒ“.", "description": "Shown in conversation banner when user's safety number has changed, but they were previously verified." }, "icu:multipleNoLongerVerified": { - "messageformat": "Your safety numbers with multiple members of this group have changed and are no longer verified. Click to show.", + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრები ამ áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ რამდენიმე წევრთან ჹეიáƒȘვალა და ა჊არ არიქ ვერიჀიáƒȘირებული. დააწკაპუნე áƒĄáƒáƒ©áƒ•áƒ”áƒœáƒ”áƒ‘áƒšáƒáƒ“.", "description": "Shown in conversation banner when more than one group member's safety number has changed, but they were previously verified." }, "icu:debugLogExplanation": { @@ -625,35 +709,35 @@ "description": "Link to open the issue tracker" }, "icu:gotIt": { - "messageformat": "Got it!", + "messageformat": "გასაგებია!", "description": "Label for a button that dismisses a dialog. The user clicks it to confirm that they understand the message in the dialog." }, "icu:submit": { - "messageformat": "Submit" + "messageformat": "დადასჱურება" }, "icu:acceptNewKey": { - "messageformat": "დასჱური", + "messageformat": "მიჩება", "description": "Label for a button to accept a new safety number" }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "მიმდინარეობს áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრების განაჼლება.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "გაიგე მეჱი", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "წინა áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "მომდევნო áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრის ვერსია, {index,number} {total,number}-დან", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "დადასჱურებულად მონიჹვნა", @@ -663,33 +747,41 @@ "messageformat": "ვერიჀიკაáƒȘიიქ áƒ’áƒáƒĄáƒŁáƒ€áƒ—áƒáƒ•áƒ”áƒ‘áƒ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name}-თან ბოლომდე áƒ“áƒáƒšáƒ˜áƒ€áƒ•áƒ áƒ˜áƒĄ დასადასჱურებლად, ჹეედარე მის მოწყობილობაჹი მოáƒȘემული áƒȘáƒ˜áƒ€áƒ áƒ”áƒ‘áƒĄ. მას ასევე áƒšáƒ”áƒŁáƒ«áƒšáƒ˜áƒ ჹენი კოდი თავისი მოწყობილობით დაასკანიროს.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "გაიგე მეჱი", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { - "messageformat": "{name}-თან ბოლომდე áƒ“áƒáƒšáƒ˜áƒ€áƒ•áƒ áƒ˜áƒĄ დასადასჱურებლად, ჹეადარე მის მოწყობილობაჹი Ⴠერად ბარათზე მოáƒȘემული áƒȘáƒ˜áƒ€áƒ áƒ”áƒ‘áƒĄ. თუ ისინი არ ემთჼვევა, áƒ’áƒáƒ“áƒáƒĄáƒ„áƒ áƒáƒšáƒ” და áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრების სჼვა წყვილი ქáƒȘადე. მჼოლოდ ერთი წყვილი უნდა ჹეესაბამებოდეს.", - "description": "Safety number viewer, text of the hint during migration period" + "messageformat": "{name}-თან ბოლომდე áƒ“áƒáƒšáƒ˜áƒ€áƒ•áƒ áƒ˜áƒĄ დასადასჱურებლად, ჹეადარე მის მოწყობილობაჹი Ⴠერად ბარათზე მოáƒȘემული áƒȘიჀრები. თუ ისინი არ ემთჼვევა, áƒ’áƒáƒ“áƒáƒĄáƒ„áƒ áƒáƒšáƒ” და áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრების სჼვა წყვილი ქáƒȘადე. მჼოლოდ ერთი წყვილი უნდა ჹეესაბამებოდეს.", + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { - "messageformat": "{name}-თან ბოლომდე áƒ“áƒáƒšáƒ˜áƒ€áƒ•áƒ áƒ˜áƒĄ დასადასჱურებლად, ჹეუსაბამე მის მოწყობილობაჹი მოáƒȘემული áƒȘიჀრები. მას ასევე áƒšáƒ”áƒŁáƒ«áƒšáƒ˜áƒ ჹენი კოდი თავისი მოწყობილობით დაასკანიროს.", - "description": "Safety number viewer, text of the hint after migration period" + "messageformat": "{name}-თან ბოლომდე áƒ“áƒáƒšáƒ˜áƒ€áƒ•áƒ áƒ˜áƒĄ დასადასჱურებლად, ჹეედარე მის მოწყობილობაჹი მოáƒȘემული áƒȘáƒ˜áƒ€áƒ áƒ”áƒ‘áƒĄ. მას ასევე áƒšáƒ”áƒŁáƒ«áƒšáƒ˜áƒ ჹენი კოდი თავისი მოწყობილობით დაასკანიროს.", + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "áƒȘვლილებები áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრებჹი", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრები აჼლდება გარდამავალი პერიოდის განმავლობაჹი, რათა áƒ©áƒáƒ áƒ—áƒáƒĄ კონჀიდენáƒȘიალურობის მომავალი áƒ€áƒŁáƒœáƒ„áƒȘიები Signal-ლი.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრების დასადასჱურებლად, ჹეუსაბამე ისინი ჹენი áƒ™áƒáƒœáƒąáƒáƒ„áƒąáƒ˜áƒĄ მოწყობილობის ბარათებს. თუ ისინი არ ემთჼვევა, áƒ’áƒáƒ“áƒáƒĄáƒ„áƒ áƒáƒšáƒ” და áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრების სჼვა წყვილი ქáƒȘადე. მჼოლოდ ერთი წყვილი უნდა ჹეესაბამებოდეს.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "დაჼმარება გჭირდება?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "გასაგებია", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი ლეიჄმნება ამ ადამიანთან მიმოწერის ჹემდეგ.", @@ -700,22 +792,22 @@ "description": "Text of 'Learn more' button of SafetyNumberNotReady modal" }, "icu:isVerified": { - "messageformat": "You have verified your safety number with {name}.", + "messageformat": "ჹენ დაადასჱურე ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-სთან.", "description": "Summary state shown at top of the safety number screen if user has verified contact." }, "icu:isNotVerified": { - "messageformat": "You have not verified your safety number with {name}.", + "messageformat": "ჹენ არ დაადასჱურე ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი {name}-სთან.", "description": "Summary state shown at top of the safety number screen if user has not verified contact." }, "icu:verified": { - "messageformat": "Verified" + "messageformat": "ვერიჀიáƒȘირებულია" }, "icu:newIdentity": { - "messageformat": "New safety number", + "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ აჼალი ნომერი", "description": "Header for a key change dialog" }, "icu:identityChanged": { - "messageformat": "Your safety number with this contact has changed. This could either mean that someone is trying to intercept your communication, or this contact simply reinstalled Signal. You may wish to verify the new safety number below." + "messageformat": "ჹენი áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომერი ამ áƒ™áƒáƒœáƒąáƒáƒ„áƒąáƒ—áƒáƒœ ჹეიáƒȘვალა. ეს ლეიძლება ნიჹნავდეს, რომ ვიჩაáƒȘ áƒȘდილობს áƒ—áƒ„áƒ•áƒ”áƒœáƒĄ კომუნიკაáƒȘიალი áƒ©áƒáƒ áƒ”áƒ•áƒáƒĄ, ან ამ áƒ™áƒáƒœáƒąáƒáƒ„áƒąáƒ›áƒ უბრალოდ გადააყენა Signal-ი. ლეგიძლია დაადასჱურო áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ აჼალი ნომერი Ⴤვემოთ." }, "icu:incomingError": { "messageformat": "ჼარვეზი ჹემომავალი ჹეჱყობინების დამუჹავებისას" @@ -817,7 +909,7 @@ "description": "An error popup when the user has attempted to add an attachment" }, "icu:fileSizeWarning": { - "messageformat": "Sorry, the selected file exceeds message size restrictions. {limit,number} {units}", + "messageformat": "უკაáƒȘრავად, áƒáƒ áƒ©áƒ”áƒŁáƒšáƒ˜ Ⴠაილი აჭარბებს ჹეჱყობინების ზომის ჹეზჩუდვებს. {limit,number}{units}", "description": "Shown in a toast if the user tries to attach too-large file" }, "icu:unableToLoadAttachment": { @@ -1267,10 +1359,6 @@ "messageformat": "ბოლო მედია-áƒ€áƒáƒ˜áƒšáƒ”áƒ‘áƒ˜áƒĄ ნაჼვა", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name}-თან ჹენი ბოლომდე áƒ“áƒáƒšáƒ˜áƒ€áƒ•áƒ áƒ˜áƒĄ áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ დასადასჱურებლად, ჹეადარე მის მოწყობილობასთან ზემოთ მოáƒȘემული ნომრები. მას ასევე áƒšáƒ”áƒŁáƒ«áƒšáƒ˜áƒ ზემოთ მოáƒȘემული QR კოდი დაასკანიროს.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "You haven't exchanged any messages with this contact yet. Your safety number with them will be available after the first message." }, @@ -1334,17 +1422,17 @@ "messageformat": "ინჀორმაáƒȘია", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "წაჹლა", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ჹეჱყობინებების წაჹლა", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "წავჹალოთ ჩაჹი?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "წავჹალოთ ჹეჱყობინებები?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ეს ჩაჹი ამ მოწყობილობიდან წაიჹლება.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ამ ჩაჹლი არსებული ჹეჱყობინებები ამ მოწყობილობიდან წაიჹლება. ჹეჱყობინებების წაჹლის ჹემდეგ ამ ჩაჹიქ áƒ›áƒáƒ«áƒ”áƒ‘áƒœáƒáƒĄ მაინáƒȘ ლეძლებ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ დაჱოვება", @@ -1438,6 +1526,14 @@ "messageformat": "ჹენი ორივე ჩაჹიქ მიმოწერის ისჱორია აჄ გაერთიანდა.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle}-ქ ეკუთვნის. ორივე {sharedGroup}-იქ წევრები ჼართ.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle}-ქ ეკუთვნის", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "სურათის მინიაჱურა áƒȘიჱირებული ჹეჱყობინებიდან", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ისევ დარეკვა", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ზარის დაწყება", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ზარზე ჹესვლა", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "მიკროჀონი დადუმებულია ზარის მოáƒȘულობის გამო", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ზარის ჹეჱყობინებები", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ზარი გადავსებულია", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "კამერა", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ჹეუერთდი", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "დაწყება", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ზარი გადავსებულია", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "კამერა გამორთულია", @@ -1621,10 +1725,6 @@ "messageformat": "კამერის ჩართვა", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "დადუმება", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "მიკროჀონი გამორთულია", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "áƒ›áƒ˜áƒ™áƒ áƒáƒ€áƒáƒœáƒ˜áƒĄ ჩართვა", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "გაზიარება", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "პრეზენჱირება გამორთულია", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "პრეზენჱირების ჹეწყვეჱა", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ზარი", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "áƒŻáƒ’áƒŁáƒ€áƒ˜ ძალიან დიდია მონაწილეებთან დასარეკად.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "რეკვის ჩართვა", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "გამორთე ზარის ჼმა", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ჩართე ზარის ჼმა", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "მეჱი ოჀáƒȘია", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ჹენ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ჹენი კამერა გამორთულია", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრის ნაჼვა", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "მიწერა", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "áƒŁáƒĄáƒáƒ€áƒ áƒ—áƒźáƒáƒ”áƒ‘áƒ˜áƒĄ ნომრის ნაჼვა", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "მობილურის ნომრის მიჩება ვერ მოჼერჼდა. ჹეამოწმე ჹენი ინჱერნეჱ კავჹირი და თავიდან ქáƒȘადე.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ჹეჱყობინების áƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘áƒ მისი გაგზავნიდან მჼოლოდ 3 საათის განმავლობაჹია ლეგიძლია.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ჹეჱყობინების áƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘áƒ მისი გაგზავნიდან მჼოლოდ 24 საათის განმავლობაჹია áƒšáƒ”áƒĄáƒáƒ«áƒšáƒ”áƒ‘áƒ”áƒšáƒ˜.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ეს ჹეჱყობინება იჄნა წაჹლილი.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "მიმაგრებული Ⴠაილი áƒĄáƒáƒ©áƒ•áƒ”áƒœáƒ”áƒ‘áƒšáƒáƒ“ ზედმეჱად დიდია.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ზოგი მიმაგრებული Ⴠაილი áƒĄáƒáƒ©áƒ•áƒ”áƒœáƒ”áƒ‘áƒšáƒáƒ“ ზედმეჱად დიდია.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "დონაáƒȘიიქ დეჱალების მიჩება ვერ მოჼერჼდა", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "áƒšáƒ”áƒĄáƒáƒ«áƒšáƒ”áƒ‘áƒ”áƒšáƒ˜áƒ მჼოლოდ Signal-იქ ბეჱა ვერსიაჹი", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ჹეჱყობინებების áƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘áƒ მჼოლოდ Signal-იქ ბეჱა ვერსიის მომჼმარებლებს áƒšáƒ”áƒŁáƒ«áƒšáƒ˜áƒáƒ—. თუ ამ ჹეჱყობინებებას áƒ“áƒáƒáƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘, მას მჼოლოდ Signal-იქ უაჼლესი ბეჱა ვერსიის მომჼმარებლები ნაჼავენ.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ჹეჱყობინების áƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘áƒ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "თუ ამ ჹეჱყობინებას áƒ“áƒáƒáƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘, მას მჼოლოდ Signal-იქ უაჼლესი ვერსიის მომჼმარებლები ნაჼავენ. იმათ áƒšáƒ”áƒĄáƒáƒ«áƒšáƒ”áƒ‘áƒšáƒáƒ‘áƒ ეჄნებათ ნაჼონ, რომ ჹეჱყობინება áƒ“áƒáƒáƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ჹემომავალი ვიდეო ზარი
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "გამავალი ჼმოვანი ზარი", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "გამავალი ვიდეო ზარი", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} გირეკავს", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "მიმდინარეობს ჼელაჼლა დაკავჹირება
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal-ი {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} ადამიანი} other {{count,number} ადამიანი}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "აუდიო ზარი", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "დასრულება", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "დაჱოვება", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "მიკროჀონი გამორთულია", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "მიკროჀონი áƒ©áƒáƒ áƒ—áƒŁáƒšáƒ˜áƒ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ზარის ჼმა áƒ©áƒáƒ áƒ—áƒŁáƒšáƒ˜áƒ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ზარის ჼმა გამორთულია", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Settings", @@ -3468,13 +3668,25 @@ "messageformat": "ზარის áƒ€áƒáƒœáƒŻáƒ áƒ˜áƒĄ მთელს ეკრანზე გადიდება", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ბადისებრ ჼედზე გადართვა", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ჼედის ჹეáƒȘვლა", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "სპიკერზე გადართვა", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ბადისებრი ჼედი", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "გვერდითი ზოლის ჼედი", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "მოსაუბრის ჼედი", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ჼედი განაჼლდა", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ზარის დაჱოვება", @@ -3576,6 +3788,14 @@ "messageformat": "კარგი", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ჹეჱყობინების áƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘áƒ áƒšáƒ”áƒŁáƒ«áƒšáƒ”áƒ‘áƒ”áƒšáƒ˜áƒ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ამ ჹეჱყობინების áƒ áƒ”áƒ“áƒáƒ„áƒąáƒ˜áƒ áƒ”áƒ‘áƒ მჼოლოდ {max,number}-ჯერ ლეიძლება.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ბოდიჹი, ამ sgnl:// ბმულს აზრი არ ჰჄონდა!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "მომჼმარებლის საჼელი", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ჹენს მომჼმარებლის საჼელს რა჊აáƒȘ მოუვიდა, იქ ჹენს მონაáƒȘემებთან ა჊არ არიქ დაკავჹირებული.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "მომჼმარებლის საჼელის წაჹლა", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ლეჄმენი მომჼმარებლის საჼელი", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR კოდი ან ბმული", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "მომჼმარებლის საჼელს გადაყენება სჭირდება", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "მომჼმარებლის საჼელის ბმულს გადაყენება სჭირდება", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "მომჼმარებლის საჼელის გაზიარება", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "მომჼმარებლის საჼელის წაჹლა", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ეს წაჹლის ჹენს მომჼმარებლის საჼელს და ნებას მისáƒȘემს სჼვა მომჼმარებლებს, იქ გამოიყენონ. დარწმუნებული ჟარ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ეს ჹენს მომჼმარებლის საჼელს წაჹლის და QR კოდსა და ბმულს áƒ’áƒáƒáƒŁáƒ„áƒ›áƒ”áƒ‘áƒĄ. \"{username}\" სჼვებისთვის ჼელმისაწვდომი გაჼდება. დარწმუნებული ჟარ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Stories-ების ნაჼვასა და გაზიარებას ვეჩარ ლეძლებ. ასევე წაიჹლება ჹენ მიერ ბოლოს გაზიარებული Story-იქ განაჼლებები.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ენა", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ენა", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "სისჱემის ენა", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ენების ძებნა", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "„{searchTerm}“-ზე ვერაჀერი მოიძებნა", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "დაყენება", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "გამოსაყენებლად გადაჱვირთე Signal-ი", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ენის ჹესაáƒȘვლელად აპი უნდა გადაიჱვირთოს.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "გადაჱვირთვა", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "განაჼლება ვერსია {version}-ზე ჼელმისაწვდომია", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ჹენი პარამეჱრების ჹენაჼვისას მოჼდა ჹეáƒȘდომა. გთჼოვთ კიდევ ქáƒȘადო.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "მიწერა", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "მეჱი ვარიანჱი", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "აჼლიდან დაყენება", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ჹესრულებულია", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "მომჼმარებლის საჼელის ბმულის Ⴠერი, {total,number}-დან {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "თუ ჹენს QR კოდს ჹეáƒȘვლი, ჹენი არსებული QR კოდი და ბმული ა჊არ იმუჹავებს.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "მიმდინარეობს ბმულის გადაყენება...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR კოდი და ბმული არ არიქ დაყენებული. ჹეამოწმე ჹენი ინჱერნეჱ-კავჹირი და თავიდან ქáƒȘადე.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ლეჄმენი ჹენი Signal-იქ მომჼმარებლის საჼელი", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "თავიდან გაგზავნა", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "მეჱი მოჄმედება", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ზარები", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "აჼალი ზარი", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "აჼალი ზარი", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "მეჱი მოჄმედება", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "ზარების ისჱორიის წაჹლა", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "წავჹალოთ ზარების ისჱორია?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ეს სამუდამოდ წაჹლის ზარების მთელ ისჱორიას", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "áƒ’áƒáƒĄáƒŁáƒ€áƒ—áƒáƒ•áƒ”áƒ‘áƒ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "ზარის ისჱორია წაიჹალა", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "დააწკაპუნე ზარის სანაჼავად ან დასაწყებად", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ძიება", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "გამოჱოვებულის მიჼედვით áƒ’áƒáƒ€áƒ˜áƒšáƒąáƒ•áƒ áƒ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "გადართვა", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ბოლოდროინდელი ზარები ვერ მოიძებნა. დაიწყე მეგობართან დარეკვით.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "„{query}“-ზე ვერაჀერი მოიძებნა", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ჹემომავალი", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "გამავალი", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "გამოჱოვებული", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "áƒŻáƒ’áƒŁáƒ€áƒŁáƒ áƒ˜ ზარი", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ბოლოდროინდელი მიმოწერები ვერ მოიძებნა.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "„{query}“-ზე ვერაჀერი მოიძებნა", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {გამავალი ჼმოვანი ზარი} other {ჹემომავალი ჼმოვანი ზარი}}} Video {{direction, select, Outgoing {გამავალი ვიდეო ზარი} other {ჹემომავალი ვიდეო ზარი}}} Group {{direction, select, Outgoing {áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ გამავალი ზარი} other {áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ ჹემომავალი ზარი}}} other {{direction, select, Outgoing {გამავალი ზარი} other {ჹემომავალი ზარი}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {გამოჱოვებული ჼმოვანი ზარი} Video {გამოჱოვებული ვიდეო ზარი} Group {áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ გამოჱოვებული ზარი} other {გამოჱოვებული ზარი}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {უპასუჼო ჼმოვანი ზარი} Video {უპასუჼო ვიდეო ზარი} Group {უპასუჼო áƒŻáƒ’áƒŁáƒ€áƒŁáƒ áƒ˜ ზარი} other {უპასუჼო ზარი}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {áƒŁáƒáƒ áƒ§áƒáƒ€áƒ˜áƒšáƒ˜ ჼმოვანი ზარი} Video {áƒŁáƒáƒ áƒ§áƒáƒ€áƒ˜áƒšáƒ˜ ვიდეო ზარი} Group {áƒŁáƒáƒ áƒ§áƒáƒ€áƒ˜áƒšáƒ˜ áƒŻáƒ’áƒŁáƒ€áƒŁáƒ áƒ˜ ზარი} other {áƒŁáƒáƒ áƒ§áƒáƒ€áƒ˜áƒšáƒ˜ ზარი}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} სჼვა ბეჭდავს.} other {{count,number} სჼვა ბეჭდავს.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "რა არიქ აჼალი", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "მáƒȘირე ჹესწორებები, ბაგების გამოსწორება და წარმადობის გაუმჯობესება. მადლობას გიჼდით სიგნალის გამოყენებისთვის!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ეს განაჼლება მოიáƒȘავს რამდენიმე გაუმჯობესებას ჼმოვანი და ვიდეო ზარებისთვის და დოკუმენჱაáƒȘიიქ რამდენიმე მáƒȘირე განაჼლებას (მადლობა, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "აჼლა უკვე ლეგიძლია, ჹენი áƒáƒ áƒ©áƒ”áƒŁáƒšáƒ˜ ენა Signal-ლი ჹენი სისჱემის პარამეჱრების ჹეáƒȘვლის გარეჹე ჹეáƒȘვალო (სიგნალის პარამეჱრები > ვიზუალი > ენა)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ჩვენ განვააჼლეთ áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ ჹეჱყობინებების ზოგიერთი ჼაჱულა. ეს ჼაჱულები ჼელს უწყობს კითჼვადობის გაუმჯობესებას, განსაკუთრებით ჩამის რეჟიმის დროს. წინა ჼაჱულები სიბნელეჹი áƒŁáƒ©áƒ˜áƒœáƒáƒ áƒ“áƒ”áƒ‘áƒáƒ“áƒœáƒ”áƒœ. აჼალი ჼაჱულები კი სიბნელიდან დაიბადნენ." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ჩვენ ჹევასწორეთ მáƒȘირე áƒšáƒ”áƒ€áƒ”áƒ áƒźáƒ”áƒ‘áƒ, რომელსაáƒȘ ჼანდაჼან macOS-ზე ზარის ლობიჹი ჹესვლის ჹემდეგ აწყდებოდი." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ჩვენ გამოვასწორეთ გარდამავალი ანიმაáƒȘია ვიდეოს áƒ€áƒáƒœáƒŻáƒ áƒ”áƒ‘áƒ˜áƒĄáƒ—áƒ•áƒ˜áƒĄ, როდესაáƒȘ ვინმე უერთდება ან ჱოვებს áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ ზარს." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "აჼლა ლეგიძლია, áƒžáƒ áƒáƒ€áƒ˜áƒšáƒ˜áƒĄ áƒ€áƒáƒąáƒáƒ–áƒ” ან ჩაჹიქ სათაურჹი áƒŻáƒ’áƒŁáƒ€áƒ˜áƒĄ ავაჱარზე დააწკაპუნო, რათა ჩაჹიქ პარამეჱრებჹი áƒĄáƒŹáƒ áƒáƒ€áƒáƒ“ გადაჼვიდე ან ამ ჩაჹიქ ნებისმიერი Srory-ი ნაჼო, რომელიáƒȘ ჯერ არ გინაჼავს. მადლობა, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/kk-KZ/messages.json b/_locales/kk-KZ/messages.json index 7a6f71c9cc..4639aa7f33 100644 --- a/_locales/kk-KZ/messages.json +++ b/_locales/kk-KZ/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ДДрДĐșÒ›ĐŸŃ€ Ò›Đ°Ń‚Đ”ŃŃ–", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ДДрДĐșÒ›ĐŸŃ€ĐŽĐ° Ò›Đ°Ń‚Đ” ŃˆŃ‹Ò›Ń‚Ń‹. ĐÒ›Đ°ŃƒĐŽŃ‹ Ń‚ÒŻĐ·Đ”Ń‚Ńƒ ÒŻŃˆŃ–Đœ Ò›Đ°Ń‚Đ”ĐœŃ– ĐșÓ©ŃˆŃ–Ń€Ń–Đż, Signal Ò›ĐŸĐ»ĐŽĐ°Ńƒ ĐșÓ©Ń€ŃĐ”Ń‚Ńƒ Ò›Ń‹Đ·ĐŒĐ”Ń‚Ń–ĐœĐ” хабарласа аласыз. ЕгДр Signal-Юы ĐŽĐ”Ń€Đ”Ńƒ Ò›ĐŸĐ»ĐŽĐ°ĐœŃƒ ĐșДрДĐș Đ±ĐŸĐ»ŃĐ°, ЎДрДĐșтДрЎі Đ¶ĐŸĐčып, ĐŸĐœŃ‹ Ó©ŃˆŃ–Ń€Ń–Đż, Ò›Đ°Đčта Ò›ĐŸŃŃ‹ÒŁŃ‹Đ·. \n\nÒšĐŸĐ»ĐŽĐ°Ńƒ ĐșÓ©Ń€ŃĐ”Ń‚Ńƒ ĐŸŃ€Ń‚Đ°Đ»Ń‹Ò“Ń‹ĐœĐ° Ń…Đ°Đ±Đ°Ń€Đ»Đ°ŃŃ‹ÒŁŃ‹Đ·: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ДДрДĐșŃ‚Ń–ÒŁ Đ±Đ°Ń€Đ»Ń‹Ò“Ń‹Đœ Đ¶ĐŸĐčып, Ò›Đ°Đčта Ò›ĐŸŃŃ‹ÒŁŃ‹Đ·", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ДДрДĐșтДрЎі Đ¶ĐŸĐčып, Ò›Đ°Đčта ісĐșĐ” Ò›ĐŸŃŃ‹ÒŁŃ‹Đ·", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ДДрДĐșŃ‚Đ”Ń€ĐŽŃ–ÒŁ Đ±Đ°Ń€Đ»Ń‹Ò“Ń‹Đœ Đ±Ń–Ń€Đ¶ĐŸĐ»Đ° Đ¶ĐŸŃŽ ĐșДрДĐș пД?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Đ„Đ°Ń‚Ń‚Đ°Ń€ĐŽŃ‹ÒŁ тарохы Đ¶Ó™ĐœĐ” ĐŒŃƒĐ»ŃŒŃ‚ĐžĐŒĐ”ĐŽĐžĐ° Ń‚ÒŻĐłĐ”Đ»ĐŽĐ”Đč ĐŸŃŃ‹ Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ĐŽĐ°Đœ Đ±Ń–Ń€Đ¶ĐŸĐ»Đ° Đ¶ĐŸĐčылып ĐșДтДЎі. ÒšĐ°Đčта баĐčĐ»Đ°ĐœŃ‹ŃŃ‚Ń‹Ń€Ò“Đ°Đœ ŃĐŸÒŁ, Đ±Ò±Đ» Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ĐŽĐ° Signal-Юы паĐčĐŽĐ°Đ»Đ°ĐœĐ° аласыз. Đ‘Ò±Đ» Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃ‹ÒŁŃ‹Đ·ĐŽĐ°Ò“Ń‹ ЎДрДĐșтДрЎі Đ¶ĐŸĐčып Đ¶Ń–Đ±Đ”Ń€ĐŒĐ”ĐčЮі.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "ДДрДĐșÒ›ĐŸŃ€ĐŽŃ‹ÒŁ ĐœÒ±ŃÒ›Đ°ŃŃ‹ Signal-ĐŽŃ‹ÒŁ Đ±Ò±Đ» ĐœÒ±ŃÒ›Đ°ŃŃ‹ĐœĐ° сәĐčĐșДс ĐșĐ”Đ»ĐŒĐ”ĐčЮі. ĐšĐŸĐŒĐżŃŒŃŽŃ‚Đ”Ń€Ń–ÒŁŃ–Đ·ĐŽĐ” Signal-ĐŽŃ‹ÒŁ ŃĐŸÒŁÒ“Ń‹ ĐœÒ±ŃÒ›Đ°ŃŃ‹Đœ ашып ĐŸŃ‚Ń‹Ń€Ò“Đ°ĐœŃ‹ÒŁĐ·Ò“Đ° ĐșÓ©Đ· жДтĐșŃ–Đ·Ń–ÒŁŃ–Đ·.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ЀаĐčĐ»", @@ -300,6 +316,70 @@ "messageformat": "Чаттар", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ÒŁŃ‹Đ·Ò“Đ° баĐčĐ»Đ°ĐœŃ‹ŃŃ‚Ń‹ Đ±Ń–Ń€ĐŽĐ”ÒŁĐ” ĐŽÒ±Ń€Ń‹Ń Đ±ĐŸĐ»ĐŒĐ°ĐŽŃ‹, ĐŸĐ» Đ”ĐœĐŽŃ– ŃŃ–Đ·ĐŽŃ–ÒŁ аĐșĐșĐ°ŃƒĐœŃ‚Ń‹ÒŁŃ‹Đ·Ò“Đ° Ń‚Đ°Ò“Đ°ĐčŃ‹ĐœĐŽĐ°Đ»Ń‹Đż Ń‚Ò±Ń€Ò“Đ°Đœ Đ¶ĐŸÒ›. ĐžĐœŃ‹ Ò›Đ°Đčта ĐŸŃ€ĐœĐ°Ń‚Ń‹Đż ĐșÓ©Ń€ŃƒŃ–ÒŁŃ–Đ·ĐłĐ” Đ±ĐŸĐ»Đ°ĐŽŃ‹ ĐœĐ”ĐŒĐ”ŃĐ” Đ¶Đ°ÒŁĐ°ŃŃ‹Đœ Ń‚Đ°ÒŁĐŽĐ°ÒŁŃ‹Đ·.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ÒšĐ°Đ·Ń–Ń€ Ń‚ÒŻĐ·Đ”Ń‚Ńƒ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "QR ĐșĐŸĐŽŃ‹ Đ¶Ó™ĐœĐ” паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ĐœĐ° ŃŃ–Đ»Ń‚Đ”ĐŒĐ”ĐłĐ” Ò›Đ°Ń‚Ń‹ŃŃ‚Ń‹ бДлгісіз Ò›Đ°Ń‚Đ” ĐŸŃ€Ń‹Đœ алЎы, ĐŸĐ»Đ°Ń€ Đ”ĐœĐŽŃ– Đ¶Đ°Ń€Đ°ĐŒŃŃ‹Đ·. Đ‘Đ°ŃÒ›Đ°Đ»Đ°Ń€ĐŒĐ”Đœ бөлісĐșŃ–ÒŁŃ–Đ· ĐșДлсД, Đ¶Đ°ÒŁĐ° ŃŃ–Đ»Ń‚Đ”ĐŒĐ” Đ¶Đ°ŃĐ°ÒŁŃ‹Đ·.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ÒšĐ°Đ·Ń–Ń€ Ń‚ÒŻĐ·Đ”Ń‚Ńƒ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ÒšĐŸĐčŃ‹ĐœĐŽŃ‹Đ»Đ°Ń€ĐŽŃ‹ ĐșÓ©Ń€ŃĐ”Ń‚Ńƒ", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ÒšĐŸĐčŃ‹ĐœĐŽŃ‹Đ»Đ°Ń€ĐŽŃ‹ Đ¶Đ°ŃŃ‹Ń€Ńƒ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ÒšĐ°Ń‚Đ” ŃˆŃ‹Ò›Ń‚Ń‹", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ĐŸÒ›Ń‹Đ»ĐŒĐ°Ò“Đ°Đœ хат", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ĐžÒ›Ń‹Đ»ĐŒĐ°Ò“Đ°Đœ ЎДп Đ±Đ”Đ»ĐłŃ–Đ»Đ”ĐœĐŽŃ–", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Чаттар", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ĐĄŃ‚ĐŸŃ€ĐžŃŃ‚Đ”Ń€", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐŸĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal-Юы Đ¶Đ°ÒŁĐ°Ń€Ń‚Ńƒ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„ĐžĐ»ŃŒ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ĐŃ€Ń‚Ò›Đ°", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Đ‘Ò±Đ» чаттар ĐŒÒ±Ń€Đ°Ò“Đ°Ń‚Ń‚Đ°Đ»ĐŽŃ‹ Đ¶Ó™ĐœĐ” тДĐș Đ¶Đ°ÒŁĐ° хаттар ĐșДлсД Ò“Đ°ĐœĐ°, ĐŸĐ» Đșіріс Đ¶Ó™ŃˆŃ–ĐłŃ–ĐœĐŽĐ” паĐčЎа Đ±ĐŸĐ»Đ°ĐŽŃ‹.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ĐĄĐŸĐœĐŽĐ° Ўа Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ шалу", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ĐĄĐŸĐœĐŽĐ° Ўа Ò›ĐŸŃŃ‹Đ»Ńƒ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ Đ¶Đ°Đ»Ò“Đ°ŃŃ‚Ń‹Ń€Ńƒ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ÒšĐ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń– Đ¶Đ°ÒŁĐ°Ń€Ń‚Ń‹Đ»Ń‹Đż жатыр.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ĐąĐŸĐ»Ń‹Ò› Đ°Ò›ĐżĐ°Ń€Đ°Ń‚", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐĐ»ĐŽŃ‹ÒŁÒ“Ń‹ Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń–", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "КДлДсі Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń–", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ÒšĐ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń–ĐœŃ–ÒŁ ĐœÒ±ŃÒ›Đ°ŃŃ‹, {index,number}/{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ВДрОфОĐșĐ°Ń†ĐžŃĐŽĐ°Đœ өтті ЎДп Đ±Đ”Đ»ĐłŃ–Đ»Đ”Ńƒ", @@ -663,33 +747,41 @@ "messageformat": "ВДрОфОĐșĐ°Ń†ĐžŃĐœŃ‹ Ń‚Đ°Đ·Đ°Đ»Đ°Ńƒ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} ĐŽĐ”ĐłĐ”Đœ ĐșĐŸĐœŃ‚Đ°ĐșŃ‚Ń–ĐŒĐ”Đœ өтпДлі ŃˆĐžŃ„Ń€Đ»Đ°Ńƒ Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–ĐłŃ–Đœ тДĐșŃĐ”Ń€Ńƒ ÒŻŃˆŃ–Đœ, Đ¶ĐŸÒ“Đ°Ń€Ń‹ĐŽĐ°Ò“Ń‹ ŃĐ°ĐœĐŽĐ°Ń€ĐŽŃ‹ ĐŸĐœŃ‹ÒŁ Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ŃŃ‹ĐŒĐ”Đœ салыстырып ĐșÓ©Ń€Ń–ÒŁŃ–Đ·. ĐĄĐŸĐœŃ‹ĐŒĐ”Đœ Ò›Đ°Ń‚Đ°Ń€ ĐŸĐ» Ó©Đ· Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ŃŃ‹ĐŒĐ”Đœ ŃŃ–Đ·ĐŽŃ–ÒŁ ĐșĐŸĐŽŃ‹ÒŁŃ‹Đ·ĐŽŃ‹ сĐșĐ°ĐœĐ”Ń€Đ»Đ”Đč алаЎы.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ĐąĐŸĐ»Ń‹Ò› Đ°Ò›ĐżĐ°Ń€Đ°Ń‚", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} ĐŽĐ”ĐłĐ”Đœ паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ĐŒĐ”Đœ өтпДлі ŃˆĐžŃ„Ń€Đ»Đ°Ńƒ Ń„ŃƒĐœĐșŃ†ĐžŃŃŃ‹Đœ тДĐșŃĐ”Ń€Ńƒ ÒŻŃˆŃ–Đœ, Đ¶ĐŸÒ“Đ°Ń€Ń‹ĐŽĐ°Ò“Ń‹ Ń‚ÒŻŃ€Đ»Ń– Ń‚ÒŻŃŃ‚Ń– ĐșĐ°Ń€Ń‚Đ°ĐœŃ‹ ĐŸĐœŃ‹ÒŁ Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ŃŃ‹ĐŒĐ”Đœ Ò›Đ°Ń‚Đ°Ń€ Ò›ĐŸĐčып, ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€ĐŽŃ– ŃĐ°Đ»Ń‹ŃŃ‚Ń‹Ń€Ń‹ÒŁŃ‹Đ·. ЕгДр ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń– сәĐčĐșДс ĐșĐ”Đ»ĐŒĐ”ŃĐ”, Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń–ĐœŃ–ÒŁ Đ±Đ°ŃÒ›Đ° Đ¶Ò±Đ±Ń‹Đœ Ò›ĐŸĐ»ĐŽĐ°ĐœŃ‹Đż ĐșÓ©Ń€Ń–ÒŁŃ–Đ·. йДĐș бір Đ¶Ò±Đż сәĐčĐșДс ĐșĐ”Đ»ŃƒŃ– ĐșДрДĐș.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} ĐŽĐ”ĐłĐ”Đœ ĐșĐŸĐœŃ‚Đ°ĐșŃ‚Ń–ĐŒĐ”Đœ өтпДлі ŃˆĐžŃ„Ń€Đ»Đ°Ńƒ Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–ĐłŃ–Đœ тДĐșŃĐ”Ń€Ńƒ ÒŻŃˆŃ–Đœ, Đ¶ĐŸÒ“Đ°Ń€Ń‹ĐŽĐ°Ò“Ń‹ ŃĐ°ĐœĐŽĐ°Ń€ĐŽŃ‹ ĐŸĐœŃ‹ÒŁ Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ŃŃ‹ĐŒĐ”Đœ салыстырып ĐșÓ©Ń€Ń–ÒŁŃ–Đ·. ĐĄĐŸĐœŃ‹ĐŒĐ”Đœ Ò›Đ°Ń‚Đ°Ń€ ĐŸĐ» Ó©Đ· Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ŃŃ‹ĐŒĐ”Đœ ŃŃ–Đ·ĐŽŃ–ÒŁ ĐșĐŸĐŽŃ‹ÒŁŃ‹Đ·ĐŽŃ‹ сĐșĐ°ĐœĐ”Ń€Đ»Đ”Đč алаЎы.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ÒšĐ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń–ĐœŃ–ÒŁ өзгДрістДрі", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal Ò›ĐŸĐ»ĐŽĐ°ĐœĐ±Đ°ŃŃ‹ĐœĐŽĐ°Ò“Ń‹ Ò›Ò±ĐżĐžŃĐ»Ń‹Đ»Ń‹Ò›Ń‚Ń‹ÒŁ Đ¶Đ°ÒŁĐ° Ń„ŃƒĐœĐșŃ†ĐžŃĐ»Đ°Ń€Ń‹Đœ Ò›ĐŸŃŃƒ ÒŻŃˆŃ–Đœ Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń– Đ°ŃƒŃ‹ŃŃ‹ĐŒ ĐșĐ”Đ·Đ”ÒŁŃ–ĐœĐŽĐ” Đ¶Đ°ÒŁĐ°Ń€Ń‚Ń‹Đ»Đ°ĐŽŃ‹.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ÒšĐ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń–Đœ тДĐșŃĐ”Ń€Ńƒ ÒŻŃˆŃ–Đœ Ń‚ÒŻŃ€Đ»Ń– Ń‚ÒŻŃŃ‚Ń– ĐșĐ°Ń€Ń‚Đ°ĐœŃ‹ ĐșĐŸĐœŃ‚Đ°ĐșŃ‚Ń–ĐœŃ–ÒŁ Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ŃŃ‹ĐŒĐ”Đœ Ò›Đ°Ń‚Đ°Ń€ Ò›ĐŸĐčŃ‹ÒŁŃ‹Đ·. ЕгДр ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń– сәĐčĐșДс ĐșĐ”Đ»ĐŒĐ”ŃĐ”, Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Đ»Đ”Ń€Ń–ĐœŃ–ÒŁ Đ±Đ°ŃÒ›Đ° Đ¶Ò±Đ±Ń‹Đœ Ò›ĐŸĐ»ĐŽĐ°ĐœŃ‹Đż ĐșÓ©Ń€Ń–ÒŁŃ–Đ·. йДĐș бір Đ¶Ò±Đż сәĐčĐșДс ĐșĐ”Đ»ŃƒŃ– ĐșДрДĐș.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ĐšÓ©ĐŒĐ”Đș ĐșДрДĐș пД?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ĐąÒŻŃŃ–ĐœŃ–Đșті", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ĐĄŃ–Đ· ĐŸŃŃ‹ ĐșŃ–ŃŃ–ĐŒĐ”Đœ хат Đ°Đ»ĐŒĐ°ŃÒ›Đ°Đœ ŃĐŸÒŁ, Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń– ĐŸŃŃ‹ Đ°ĐŽĐ°ĐŒĐŒĐ”Đœ жасалаЎы.", @@ -1267,10 +1359,6 @@ "messageformat": "ĐĄĐŸÒŁÒ“Ń‹ ĐŒŃƒĐ»ŃŒŃ‚ĐžĐŒĐ”ĐŽĐžĐ°ĐœŃ‹ ĐșÓ©Ń€Ńƒ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} Đ°Ń€Ò›Ń‹Đ»Ń‹ өтпДлі ŃˆĐžŃ„Ń€Đ»Đ°ŃƒĐŽŃ‹ÒŁ Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–ĐłŃ–Đœ тДĐșŃĐ”Ń€Ńƒ ÒŻŃˆŃ–Đœ, Đ¶ĐŸÒ“Đ°Ń€Ń‹ĐŽĐ°Ò“Ń‹ ŃĐ°ĐœĐŽĐ°Ń€ĐŽŃ‹ ĐŸŃŃ‹ Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ĐŒĐ”Đœ ŃĐ°Đ»Ń‹ŃŃ‚Ń‹Ń€Ń‹ÒŁŃ‹Đ·. ĐĄĐŸĐœŃ‹ĐŒĐ”Đœ Ò›Đ°Ń‚Đ°Ń€ ĐŸĐ» Đ¶ĐŸÒ“Đ°Ń€Ń‹ĐŽĐ°Ò“Ń‹ QR ĐșĐŸĐŽŃ‹Đœ сĐșĐ°ĐœĐ”Ń€Đ»Đ”Đč алаЎы.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Đ‘Ò±Đ» ĐșĐŸĐœŃ‚Đ°ĐșŃ‚Ń–ĐŒĐ”Đœ әлі хат Đ°Đ»ĐŒĐ°ŃĐżĐ°ĐŽŃ‹ÒŁŃ‹Đ·. ĐžĐœŃ‹ĐŒĐ”Đœ Ò›Đ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń–ÒŁŃ–Đ· Đ±Ń–Ń€Ń–ĐœŃˆŃ– хат Đ°Đ»ĐŒĐ°ŃÒ›Đ°ĐœĐœĐ°Đœ ĐșĐ”ĐčŃ–Đœ Đ±ĐŸĐ»Đ°ĐŽŃ‹." }, @@ -1334,17 +1422,17 @@ "messageformat": "ĐÒ›ĐżĐ°Ń€Đ°Ń‚", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Đ–ĐŸŃŽ", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ЄаттарЎы Đ¶ĐŸŃŽ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Чатты Đ¶ĐŸŃŽ ĐșДрДĐș пД?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ЄаттарЎы Đ¶ĐŸŃŽ ĐșДрДĐș пД?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Đ‘Ò±Đ» чат Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ĐŽĐ°Đœ Đ¶ĐŸĐčылаЎы.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Осы Ń‡Đ°Ń‚Ń‚Đ°Ò“Ń‹ хаттар Đ±Ò±Đ» Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹ĐŽĐ°Đœ Đ¶ĐŸĐčылаЎы. ЄаттарЎы Đ¶ĐŸĐčÒ“Đ°Đœ ŃĐŸÒŁ Ўа, Đ±Ò±Đ» чатты ізЎДп Ń‚Đ°Đ±ŃƒŃ‹ÒŁŃ‹Đ·Ò“Đ° Đ±ĐŸĐ»Đ°ĐŽŃ‹.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ĐąĐŸĐżŃ‚Đ°Đœ ŃˆŃ‹Ò“Ń‹Đż ĐșĐ”Ń‚Ńƒ", @@ -1438,6 +1526,14 @@ "messageformat": "ЕĐșі Ń‡Đ°Ń‚Ń‚Ń‹ÒŁ Ўа хаттар тарохы ĐŸŃŃ‹ жДрЎД біріĐșтірілЎі.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} ĐœÓ©ĐŒŃ–Ń€Ń– {conversationTitle} ĐŽĐ”ĐłĐ”Đœ ĐșісігД тОДсілі. ЕĐșĐ”ŃƒŃ–ÒŁŃ–Đ· ĐŽĐ” {sharedGroup} Ń‚ĐŸĐ±Ń‹ĐœĐ° ĐŒÒŻŃˆĐ” Đ±ĐŸĐ»Ń‹Đż ĐșДлДсізЎДр.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} ĐœÓ©ĐŒŃ–Ń€Ń– {conversationTitle} ĐŽĐ”ĐłĐ”Đœ ĐșісігД тОДсілі", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ĐĄŃ–Đ»Ń‚Đ”ĐŒĐ” Đ¶Đ°ŃĐ°Đ»Ò“Đ°Đœ Ń…Đ°Ń‚Ń‚Đ°Ò“Ń‹ ŃŃƒŃ€Đ”Ń‚Ń‚Ń–ÒŁ ĐœĐŸĐ±Đ°Đčы", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ÒšĐ°Đčта Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ шалу", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ Đ±Đ°ŃŃ‚Đ°Ńƒ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒÒ“Đ° Ò›ĐŸŃŃ‹Đ»Ńƒ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ÒŁ Ó©Đ»ŃˆĐ”ĐŒŃ–ĐœĐ” баĐčĐ»Đ°ĐœŃ‹ŃŃ‚Ń‹ ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ Ўыбысы Ó©ŃˆŃ–Ń€Ń–Đ»ĐŽŃ–", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°Ńƒ Ń‚ŃƒŃ€Đ°Đ»Ń‹ Ń…Đ°Đ±Đ°Ń€Đ»Đ°ĐœĐŽŃ‹Ń€ŃƒĐ»Đ°Ń€", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒÒ“Đ° Đ±Ò±ĐŽĐ°Đœ Đ°Ń€Ń‚Ń‹Ò› Đ°ĐŽĐ°ĐŒ Ò›ĐŸŃŃ‹Đ»Đ° Đ°Đ»ĐŒĐ°ĐčЮы", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ÒšĐŸŃŃ‹Đ»Ńƒ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Бастау", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽĐ° ĐŸŃ€Ń‹Đœ Đ¶ĐŸÒ›", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ° Ó©ŃˆŃ–Ń€Ń–Đ»ĐŽŃ–", @@ -1621,10 +1725,6 @@ "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°ĐœŃ‹ Ò›ĐŸŃŃƒ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Đ”Ń‹Đ±Ń‹ŃŃ‹Đœ Ó©ŃˆŃ–Ń€Ńƒ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ Ó©ŃˆŃ–Ń€Ń–Đ»ĐŽŃ–", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœĐœŃ‹ÒŁ ĐŽŃ‹Đ±Ń‹ŃŃ‹Đœ Ò›ĐŸŃŃƒ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Đ‘Ó©Đ»Ń–ŃŃƒ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Đ­ĐșŃ€Đ°ĐœĐŽŃ‹ Đ±Ó©Đ»Ń–ŃŃƒ Ó©ŃˆŃ–Ń€Ń–Đ»ĐŽŃ–", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Đ­ĐșŃ€Đ°ĐœĐŽŃ‹ Đ±Ó©Đ»Ń–ŃŃƒĐŽŃ– Ń‚ĐŸÒ›Ń‚Đ°Ń‚Ńƒ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°Ńƒ шалу", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ÒšĐ°Ń‚Ń‹ŃŃƒŃˆŃ‹Đ»Đ°Ń€Ò“Đ° Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ ŃˆĐ°Đ»Ń‹Đż ŃˆŃ‹Ò“Ńƒ ĐŒÒŻĐŒĐșŃ–Đœ Đ”ĐŒĐ”Ń. ĐąĐŸĐż өтД ÒŻĐ»ĐșĐ”Đœ.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ Ò›ĐŸŃŃƒ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°Ńƒ ĐŽŃ‹Đ±Ń‹ŃŃ‹Đœ Ó©ŃˆŃ–Ń€Ńƒ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ Ò›ĐŸŃŃƒ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ÒšĐŸŃŃ‹ĐŒŃˆĐ° ĐŸĐżŃ†ĐžŃĐ»Đ°Ń€", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ĐĄŃ–Đ·", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°ÒŁŃ‹Đ· Ó©ŃˆŃ–Ń€ŃƒĐ»Ń–", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ÒšĐ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń–Đœ ĐșÓ©Ń€Ńƒ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Єат", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ÒšĐ°ŃƒŃ–ĐżŃŃ–Đ·ĐŽŃ–Đș ĐœÓ©ĐŒŃ–Ń€Ń–Đœ ĐșÓ©Ń€Ńƒ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ĐąĐ”Đ»Đ”Ń„ĐŸĐœ ĐœÓ©ĐŒŃ–Ń€Ń–Đœ алу ĐŒÒŻĐŒĐșŃ–Đœ Đ±ĐŸĐ»ĐŒĐ°ĐŽŃ‹. БаĐčĐ»Đ°ĐœŃ‹ŃŃ‚Ń‹ тДĐșсДріп, Ò›Đ°Đčталап ĐșÓ©Ń€Ń–ÒŁŃ–Đ·.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Đ‘Ò±Đ» хатты Đ¶Ń–Đ±Đ”Ń€ĐłĐ”Đœ ŃĐŸÒŁ, 3 ŃĐ°Ò“Đ°Ń‚Ń‚Ń‹ÒŁ Ń–ŃˆŃ–ĐœĐŽĐ” Ò“Đ°ĐœĐ° Ó©ÒŁĐŽĐ”ŃƒĐ»Đ”Ń€ĐŽŃ– Ò›ĐŸĐ»ĐŽĐ°ĐœŃƒÒ“Đ° Đ±ĐŸĐ»Đ°ĐŽŃ‹.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Đ‘Ò±Đ» хатты Đ¶Ń–Đ±Đ”Ń€ĐłĐ”Đœ ŃĐŸÒŁ, ĐŸĐœŃ‹ 24 ŃĐ°Ò“Đ°Ń‚Ń‚Ń‹ÒŁ Ń–ŃˆŃ–ĐœĐŽĐ” Ò“Đ°ĐœĐ° Ó©Đ·ĐłĐ”Ń€Ń‚ŃƒĐłĐ” Đ±ĐŸĐ»Đ°ĐŽŃ‹.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Đ‘Ò±Đ» хат Đ¶ĐŸĐčылЎы.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "бірĐșĐ”ĐŒĐ” өтД ÒŻĐ»ĐșĐ”Đœ Đ±ĐŸĐ»Ò“Đ°ĐœĐŽŃ‹Ò›Ń‚Đ°Đœ, ĐŸĐœŃ‹ ĐșÓ©Ń€ŃĐ”Ń‚Ńƒ ĐŒÒŻĐŒĐșŃ–Đœ Đ”ĐŒĐ”Ń.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "КДĐčбір тірĐșĐ”ĐŒĐ”Đ»Đ”Ń€ өтД ÒŻĐ»ĐșĐ”Đœ Đ±ĐŸĐ»Ò“Đ°ĐœĐŽŃ‹Ò›Ń‚Đ°Đœ, ĐŸĐœŃ‹ ĐșÓ©Ń€ŃĐ”Ń‚Ńƒ ĐŒÒŻĐŒĐșŃ–Đœ Đ”ĐŒĐ”Ń.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Đ”Đ”ĐŒĐ”ŃƒŃˆŃ–Đ»Ń–Đș Ń‚ŃƒŃ€Đ°Đ»Ń‹ ĐŒÓ™Đ»Ń–ĐŒĐ”Ń‚Ń‚Ń– алу ĐŒÒŻĐŒĐșŃ–Đœ Đ±ĐŸĐ»ĐŒĐ°ĐŽŃ‹", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal бДта ĐœÒ±ŃÒ›Đ°ŃŃ‹ Ò“Đ°ĐœĐ°", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ЄаттарЎы тДĐș Signal бДта ĐœÒ±ŃÒ›Đ°ŃŃ‹Đœ паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹Đ»Đ°Ń€ Ò“Đ°ĐœĐ° Ń‚ÒŻĐ·Đ”Ń‚Đ” алаЎы. ЕгДр сіз хатты Ń‚ÒŻĐ·Đ”Ń‚ŃĐ”ÒŁŃ–Đ·, ĐŸĐ» Signal-ĐŽŃ‹ÒŁ Đ”ÒŁ ŃĐŸÒŁÒ“Ń‹ бДта ĐœÒ±ŃÒ›Đ°ŃŃ‹Đœ паĐčĐŽĐ°Đ»Đ°ĐœĐ°Ń‚Ń‹ĐœĐŽĐ°Ń€Ò“Đ° Ò“Đ°ĐœĐ° ĐșÓ©Ń€Ń–ĐœĐ”ĐŽŃ–.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Єатты Ó©Đ·ĐłĐ”Ń€Ń‚Ńƒ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ЕгДр сіз хатты Ń‚ÒŻĐ·Đ”Ń‚ŃĐ”ÒŁŃ–Đ·, ĐŸĐ» Signal-ĐŽŃ‹ÒŁ Đ”ÒŁ ŃĐŸÒŁÒ“Ń‹ ĐœÒ±ŃÒ›Đ°Đ»Đ°Ń€Ń‹Đœ паĐčĐŽĐ°Đ»Đ°ĐœĐ°Ń‚Ń‹ĐœĐŽĐ°Ń€Ò“Đ° Ò“Đ°ĐœĐ° ĐșÓ©Ń€Ń–ĐœĐ”ĐŽŃ–. Олар ŃŃ–Đ·ĐŽŃ–ÒŁ хатты өзгДртĐșĐ”ĐœŃ–ÒŁŃ–Đ·ĐŽŃ– ĐșөрД алаЎы.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Кіріс ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "ĐšŃ‹Ò“Ń‹Ń ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ĐšŃ‹Ò“Ń‹Ń ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} сізгД Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ ŃˆĐ°Đ»Ń‹Đż жатыр", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "БаĐčĐ»Đ°ĐœŃ‹Ń Ò›Đ°Đčта ĐŸŃ€ĐœĐ°Ń‚Ń‹Đ»ŃƒĐŽĐ°...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} Đ°ĐŽĐ°ĐŒ} other {{count,number} Đ°ĐŽĐ°ĐŒ}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ĐŃƒĐŽĐžĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ĐŃÒ›Ń‚Đ°Ńƒ", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ĐšŃ‹Ò“Ń‹Đż ĐșĐ”Ń‚Ńƒ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ Ó©ŃˆŃ–Ń€ŃƒĐ»Ń–", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ Ò›ĐŸŃŃƒĐ»Ń‹", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°Ńƒ Юауысы Ò›ĐŸŃŃ‹Đ»ĐŽŃ‹", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°Ńƒ Ўыбысы Ó©ŃˆŃ–Ń€Ń–Đ»ĐŽŃ–", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐŸĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€", @@ -3468,13 +3668,25 @@ "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ Ń‚ĐŸĐ»Ń‹Ò› эĐșŃ€Đ°ĐœĐŽĐ° ашу", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐąĐŸŃ€Đ»Ń‹ ĐșÓ©Ń€Ń–ĐœŃ–ŃŃ‚Ń– Ò›ĐŸŃŃƒ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ĐšÓ©Ń€Ń–ĐœŃ–ŃŃ‚Ń– Ó©Đ·ĐłĐ”Ń€Ń‚Ńƒ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Đ”ĐžĐœĐ°ĐŒĐžĐș ĐșÓ©Ń€Ń–ĐœŃ–ŃŃ–ĐœĐ” Ò›ĐŸŃŃ‹Đ»Ńƒ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ĐąĐŸŃ€Đ»Ń‹ ĐșÓ©Ń€Ń–ĐœŃ–Ń", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Đ‘ÒŻĐčірліĐș Ń‚Đ°Ò›Ń‚Đ° ĐșÓ©Ń€Ń–ĐœŃ–ŃŃ–", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Đ”ĐžĐœĐ°ĐŒĐžĐș ĐșÓ©Ń€Ń–ĐœŃ–ŃŃ–", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ĐšÓ©Ń€Ń–ĐœŃ–Ń Đ¶Đ°ÒŁĐ°Ń€Ń‚Ń‹Đ»ĐŽŃ‹", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽĐ°Đœ ŃˆŃ‹Ò“Ńƒ", @@ -3576,6 +3788,14 @@ "messageformat": "ЖараĐčЮы", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Єатты Ó©Đ·ĐłĐ”Ń€Ń‚Ńƒ ĐŒÒŻĐŒĐșŃ–Đœ Đ”ĐŒĐ”Ń", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Đ‘Ò±Đ» Ń…Đ°Ń‚Ò›Đ° тДĐș {max,number} өзгДріс Đ”ĐœĐłŃ–Đ·ŃƒĐłĐ” Đ±ĐŸĐ»Đ°ĐŽŃ‹.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ĐšĐ”ŃˆŃ–Ń€Ń–ÒŁŃ–Đ·, sgnl:// ŃŃ–Đ»Ń‚Đ”ĐŒĐ”ŃŃ– Đ¶Đ°Ń€Đ°ĐŒŃŃ‹Đ·! ", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ аты", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ÒŁŃ‹Đ·Ò“Đ° баĐčĐ»Đ°ĐœŃ‹ŃŃ‚Ń‹ Đ±Ń–Ń€ĐŽĐ”ÒŁĐ” ĐŽÒ±Ń€Ń‹Ń Đ±ĐŸĐ»ĐŒĐ°ĐŽŃ‹, ĐŸĐ» Đ”ĐœĐŽŃ– ŃŃ–Đ·ĐŽŃ–ÒŁ аĐșĐșĐ°ŃƒĐœŃ‚Ń‹ÒŁŃ‹Đ·Ò“Đ° Ń‚Đ°Ò“Đ°ĐčŃ‹ĐœĐŽĐ°Đ»Ń‹Đż Ń‚Ò±Ń€Ò“Đ°Đœ Đ¶ĐŸÒ›.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹Đœ Ó©ŃˆŃ–Ń€Ńƒ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹Đœ жасау", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ĐșĐŸĐŽŃ‹ ĐœĐ”ĐŒĐ”ŃĐ” ŃŃ–Đ»Ń‚Đ”ĐŒĐ”", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹Đœ Ò›Đ°Đčта ĐŸŃ€ĐœĐ°Ń‚Ńƒ ĐșДрДĐș", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ĐœŃ‹ÒŁ ŃŃ–Đ»Ń‚Đ”ĐŒĐ”ŃŃ–Đœ Ò›Đ°Đčта ĐŸŃ€ĐœĐ°Ń‚Ńƒ ĐșДрДĐș", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ Đ±Ó©Đ»Ń–ŃŃƒ", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹Đœ Ó©ŃˆŃ–Ń€Ńƒ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Đ‘Ò±Đ» Ń„ŃƒĐœĐșцоя ŃŃ–Đ·ĐŽŃ–ÒŁ паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ Ó©ŃˆŃ–Ń€Đ”ĐŽŃ–, ŃĐŸĐœĐŽŃ‹Ò›Ń‚Đ°Đœ ĐŸĐœŃ‹ Đ±Đ°ŃÒ›Đ° паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹Đ»Đ°Ń€ ала алаЎы. ĐĄĐ”ĐœŃ–ĐŒĐŽŃ–ŃŃ–Đ· бД?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ол паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ Đ¶ĐŸŃĐŽŃ‹ Đ¶Ó™ĐœĐ” QR ĐșĐŸĐŽŃ‹ÒŁŃ‹Đ· Đ±Đ”Đœ ŃŃ–Đ»Ń‚Đ”ĐŒĐ”ĐœŃ– Ó©ŃˆŃ–Ń€Đ”ĐŽŃ–. “{username}” Đ±Đ°ŃÒ›Đ°Đ»Đ°Ń€Ò“Đ° Ò›ĐŸĐ»Đ¶Đ”Ń‚Ń–ĐŒĐŽŃ– Đ±ĐŸĐ»Đ°ĐŽŃ‹. ĐĄĐ”ĐœŃ–ĐŒĐŽŃ–ŃŃ–Đ· бД?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Đ•ĐœĐŽŃ–ĐłÓ™Ń€Ń– ŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ”Ń€ĐŽŃ– бөлісД ĐœĐ”ĐŒĐ”ŃĐ” ĐșөрД Đ°Đ»ĐŒĐ°Đčсыз. Đ–Đ°Ò›Ń‹ĐœĐŽĐ° бөлісĐșĐ”Đœ ŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ”ĐłŃ– өзгДрістДр ĐŽĐ” Đ¶ĐŸĐčылаЎы.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "йіл", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "йіл", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Đ–ÒŻĐčĐ” тілі", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "йілЎДрЎі Ń–Đ·ĐŽĐ”Ńƒ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "\"{searchTerm}\" Đ±ĐŸĐčŃ‹ĐœŃˆĐ° ĐœÓ™Ń‚ĐžĐ¶Đ”Đ»Đ”Ń€ Đ¶ĐŸÒ›", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ĐžŃ€ĐœĐ°Ń‚Ńƒ", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ÒšĐŸĐ»ĐŽĐ°ĐœŃƒ ÒŻŃˆŃ–Đœ Signal-Юы Ó©ŃˆŃ–Ń€Ń–Đż, Ò›Đ°Đčта Ò›ĐŸŃŃ‹ÒŁŃ‹Đ·", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "йілЎі Ó©Đ·ĐłĐ”Ń€Ń‚Ńƒ ÒŻŃˆŃ–Đœ Ò›ĐŸĐ»ĐŽĐ°ĐœĐ±Đ°ĐœŃ‹ Ó©ŃˆŃ–Ń€Ń–Đż, Ò›Đ°Đčта Ò›ĐŸŃŃƒ ĐșДрДĐș.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ӹшіріп, Ò›Đ°Đčта Ò›ĐŸŃŃƒ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} ĐœÒ±ŃÒ›Đ°ŃŃ‹ĐœĐ° Đ¶Đ°ÒŁĐ°Ń€Ń‚ŃƒÒ“Đ° Đ±ĐŸĐ»Đ°ĐŽŃ‹", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ĐŸĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€ĐŽŃ– ŃĐ°Ò›Ń‚Đ°Ńƒ ĐșĐ”Đ·Ń–ĐœĐŽĐ” Ò›Đ°Ń‚Đ” ŃˆŃ‹Ò›Ń‚Ń‹. ÒšĐ°Đčталап ĐșÓ©Ń€Ń–ÒŁŃ–Đ·.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Єат", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Đ‘Đ°ŃÒ›Đ° ŃŃ‚ĐžĐ»ŃŒĐŽĐ”Ń€", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Đ‘Đ°ŃŃ‚Đ°ĐżÒ›Ń‹ ĐșÒŻĐčгД Ò›Đ°Đčтару", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ДаĐčŃ‹Đœ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ПаĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ аты ŃŃ–Đ»Ń‚Đ”ĐŒĐ”ŃŃ–ĐœŃ–ÒŁ Ń‚ÒŻŃŃ–, {index,number}/{total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ЕгДр QR ĐșĐŸĐŽŃ‹Đœ Ò›Đ°Đ»ĐżŃ‹ĐœĐ° ĐșĐ”Đ»Ń‚Ń–Ń€ŃĐ”ÒŁŃ–Đ·, ДсĐșі QR ĐșĐŸĐŽŃ‹ ĐŒĐ”Đœ ŃŃ–Đ»Ń‚Đ”ĐŒĐ” Đ¶Đ°Ń€Đ°ĐŒŃŃ‹Đ· Đ±ĐŸĐ»Ń‹Đż Ò›Đ°Đ»Đ°ĐŽŃ‹.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ĐĄŃ–Đ»Ń‚Đ”ĐŒĐ” Ò›Đ°Đčта ĐŸŃ€ĐœĐ°Ń‚Ń‹Đ»ŃƒĐŽĐ°...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR ĐșĐŸĐŽŃ‹ Đ¶Ó™ĐœĐ” ŃŃ–Đ»Ń‚Đ”ĐŒĐ” ĐŸŃ€ĐœĐ°Ń‚Ń‹Đ»ĐŒĐ°ĐŽŃ‹. ЖДлі баĐčĐ»Đ°ĐœŃ‹ŃŃ‹Đœ тДĐșсДріп, Ò›Đ°Đčталап ĐșÓ©Ń€Ń–ÒŁŃ–Đ·.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Signal-ĐŽĐ°Ò“Ń‹ паĐčĐŽĐ°Đ»Đ°ĐœŃƒŃˆŃ‹ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ ĐŸŃ€ĐœĐ°Ń‚Ń‹ÒŁŃ‹Đ·", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "өзгДртілЎі", + "messageformat": "ӚзгДртілЎі", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ÒšĐ°ĐčŃ‚Đ°ĐŽĐ°Đœ Đ¶Ń–Đ±Đ”Ń€Ńƒ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Đ‘Đ°ŃÒ›Đ° әрДĐșДттДр", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Đ–Đ°ÒŁĐ° Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Đ–Đ°ÒŁĐ° Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Đ‘Đ°ŃÒ›Đ° әрДĐșДттДр", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€ Ń‚Đ°Ń€ĐžŃ…Ń‹Đœ Ó©ŃˆŃ–Ń€Ńƒ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€ Ń‚Đ°Ń€ĐžŃ…Ń‹Đœ Ó©ŃˆŃ–Ń€Ńƒ ĐșДрДĐș пД?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Đ‘Ò±Đ» Ò›ĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€ Ń‚Đ°Ń€ĐžŃ…Ń‹Đœ Ń‚ÒŻĐłĐ”Đ»ĐŽĐ”Đč Đ±Ń–Ń€Đ¶ĐŸĐ»Đ° Đ¶ĐŸŃĐŽŃ‹", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "йазалау", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€ тарохы Ń‚Đ°Đ·Đ°Đ»Đ°ĐœĐŽŃ‹", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ÒšĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ ĐșÓ©Ń€Ńƒ ĐœĐ”ĐŒĐ”ŃĐ” Đ±Đ°ŃŃ‚Đ°Ńƒ ÒŻŃˆŃ–Đœ Đ±Đ°ŃŃ‹ÒŁŃ‹Đ·", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Đ†Đ·ĐŽĐ”Ńƒ", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ Ò›ĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€ĐŽŃ‹ Ò“Đ°ĐœĐ° ĐșÓ©Ń€ŃĐ”Ń‚Ńƒ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Ауыстыру", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĐĄĐŸÒŁÒ“Ń‹ Ò›ĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€ Đ¶ĐŸÒ›. Đ”ĐŸŃŃ‹ÒŁŃ‹Đ·Ò“Đ° Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ ŃˆĐ°Đ»ŃƒĐŽĐ°Đœ Đ±Đ°ŃŃ‚Đ°ÒŁŃ‹Đ·.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "\"{query}\" Đ±ĐŸĐčŃ‹ĐœŃˆĐ° ĐœÓ™Ń‚ĐžĐ¶Đ”Đ»Đ”Ń€ Đ¶ĐŸÒ›", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Кіріс", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ĐšŃ‹Ò“Ń‹Ń", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ĐąĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĐĄĐŸÒŁÒ“Ń‹ ŃÒ±Ń…Đ±Đ°Ń‚Ń‚Đ°Ń€ Đ¶ĐŸÒ›.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "\"{query}\" Đ±ĐŸĐčŃ‹ĐœŃˆĐ° ĐœÓ™Ń‚ĐžĐ¶Đ”Đ»Đ”Ń€ Đ¶ĐŸÒ›", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {ĐšŃ‹Ò“Ń‹Ń ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {Кіріс ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ}}} Video {{direction, select, Outgoing {ĐšŃ‹Ò“Ń‹Ń ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {Кіріс ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ}}} Group {{direction, select, Outgoing {ĐšŃ‹Ò“Ń‹Ń Ń‚ĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {Кіріс Ń‚ĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ}}} other {{direction, select, Outgoing {ĐšŃ‹Ò“Đ°Ń‚Ń‹Đœ Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {ĐšĐ”Đ»Đ”Ń‚Ń–Đœ Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ }}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} Video {Đ’ĐžĐŽĐ”ĐŸ Ò›ĐŸÒŁŃ‹Ń€Đ°ŃƒĐŽŃ‹ Ó©Ń‚ĐșŃ–Đ·Ń–Đż Đ°Đ»ĐŽŃ‹ÒŁŃ‹Đ·} Group {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ Ń‚ĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Жауап Đ±Đ”Ń€Ń–Đ»ĐŒĐ”ĐłĐ”Đœ ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} Video {Жауап Đ±Đ”Ń€Ń–Đ»ĐŒĐ”ĐłĐ”Đœ ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} Group {Жауап Đ±Đ”Ń€Ń–Đ»ĐŒĐ”ĐłĐ”Đœ Ń‚ĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {Жауап Đ±Đ”Ń€Ń–Đ»ĐŒĐ”ĐłĐ”Đœ Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} Video {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} Group {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ Ń‚ĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ} other {ÒšĐ°Đ±Ń‹Đ»ĐŽĐ°ĐœĐ±Đ°Ò“Đ°Đœ Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {ĐąĐ°Ò“Ń‹ {count,number} Đ°ĐŽĐ°ĐŒ жазып жатыр.} other {ĐąĐ°Ò“Ń‹ {count,number} Đ°ĐŽĐ°ĐŒ жазып жатыр.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Đ–Đ°ÒŁĐ°Đ»Ń‹Ò›Ń‚Đ°Ń€", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ĐšŃ–ŃˆŃ–ĐłŃ–Ń€Ń–ĐŒ Ń‚ÒŻĐ·Đ”Ń‚ĐżĐ”Đ»Đ”Ń€ жасалЎы, Đ°Ò›Đ°ŃƒĐ»Đ°Ń€ Đ¶Ó©ĐœĐŽĐ”Đ»ĐŽŃ– Đ¶Ó™ĐœĐ” Đ¶Ò±ĐŒŃ‹ŃŃ‹ Đ¶Đ°Ò›ŃĐ°Ń€Ń‚Ń‹Đ»ĐŽŃ‹. Signal-Юы Ò›ĐŸĐ»ĐŽĐ°ĐœÒ“Đ°ĐœŃ‹ÒŁŃ‹Đ· ÒŻŃˆŃ–Đœ Ń€Đ°Ò›ĐŒĐ”Ń‚!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Đ‘Ò±Đ» ĐœÒ±ŃÒ›Đ°ĐŽĐ° ĐŽĐ°ŃƒŃ‹ŃŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€Ò“Đ° Đ¶Ó™ĐœĐ” ĐČĐžĐŽĐ”ĐŸÒ›ĐŸÒŁŃ‹Ń€Đ°ŃƒĐ»Đ°Ń€Ò“Đ° Đ±Ń–Ń€Ò›Đ°Ń‚Đ°Ń€ өзгДрістДр Đ”ĐœĐłŃ–Đ·Ń–Đ»ĐŽŃ– Đ¶Ó™ĐœĐ” Ò›Ò±Đ¶Đ°Ń‚Ń‚Đ°ĐŒĐ°ĐŽĐ° Đ°Đ·ĐŽĐ°Ò“Đ°Đœ өзгДрістДр бар (Ń€Đ°Ò›ĐŒĐ”Ń‚, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Đ•ĐœĐŽŃ– Đ¶ÒŻĐčĐ” ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€Ń–Đœ Ó©Đ·ĐłĐ”Ń€Ń‚ĐżĐ”ŃŃ‚Đ”Đœ Signal-Ўа Ń‚Đ°ÒŁĐŽĐ°Đ»Ò“Đ°Đœ тілЎі өзгДртД аласыз (Signal ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€Ń– > ĐĄŃ‹Ń€Ń‚Ò›Ń‹ ĐșÓ©Ń€Ń–ĐœŃ–Ń > йіл)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ĐąĐŸĐżŃ‚Đ°Ò“Ń‹ өзгДрістДргД Ò›Đ°Ń‚Ń‹ŃŃ‚Ń‹ (ĐŒŃ‹ŃĐ°Đ»Ń‹, Ń‚ĐŸĐżÒ›Đ° Đ¶Đ°ÒŁĐ° Đ°ĐŽĐ°ĐŒ Ò›ĐŸŃŃ‹Đ»Ò“Đ°Đœ ĐșДзЎД) паĐčЎа Đ±ĐŸĐ»Đ°Ń‚Ń‹Đœ Ń…Đ°Đ±Đ°Ń€Đ»Đ°ĐœĐŽŃ‹Ń€Ńƒ Đ±Đ”Đ»ĐłŃ–ŃˆĐ”Đ»Đ”Ń€Ń–Đœ өзгДрттіĐș. Đ‘Ò±Đ» Đ±Đ”Đ»ĐłŃ–ŃˆĐ”Đ»Đ”Ń€, әсірДсД ÒšĐ°Ń€Đ°ÒŁÒ“Ń‹ Ń‚Đ°Ò›Ń‹Ń€Ń‹ĐżŃ‚Ń‹ паĐčĐŽĐ°Đ»Đ°ĐœÒ“Đ°ĐœĐŽĐ°, ĐŸÒ›ŃƒĐŽŃ‹ Đ¶Đ”ÒŁŃ–Đ»ĐŽĐ”Ń‚Đ”ĐŽŃ–. ĐĐ»ĐŽŃ‹ÒŁÒ“Ń‹ Đ±Đ”Đ»ĐłŃ–ŃˆĐ”Đ»Đ”Ń€ Ò›Đ°Ń€Đ°ÒŁÒ“Ń‹ Ń„ĐŸĐœĐŽŃ‹ Ò›Đ°Đ±Ń‹Đ»ĐŽĐ°ĐŽŃ‹. ĐžĐœŃ‹ÒŁ Ń–ŃˆŃ–ĐœĐŽĐ” Đ¶Đ°ÒŁĐ° Đ±Đ”Đ»ĐłŃ–ŃˆĐ”Đ»Đ”Ń€ паĐčЎа Đ±ĐŸĐ»Ń‹Đż, ŃĐŸĐ»Đ°Ń€Ò“Đ° бДĐčŃ–ĐŒĐŽĐ”Đ»ĐŽŃ–." + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOS Ò›Ò±Ń€Ń‹Đ»Ò“Ń‹Đ»Đ°Ń€Ń‹ĐœĐŽĐ°Ò“Ń‹ Ò›ĐŸÒŁŃ‹Ń€Đ°Ńƒ Đ»ĐŸĐ±Đ±ĐžŃ–ĐœĐ” Ò›ĐŸŃŃ‹Đ»Ń‹Đż Đ¶Đ°Ń‚Ò›Đ°ĐœĐŽĐ° ĐșĐ”ĐčĐŽĐ” паĐčЎа Đ±ĐŸĐ»Đ°Ń‚Ń‹Đœ ŃˆĐ°ĐŒĐ°Đ»Ń‹ ĐșĐ”ŃˆŃ–ĐłŃƒ Đ¶Đ°Ò“ĐŽĐ°ĐčĐ»Đ°Ń€Ń‹Đœ Ń‚ÒŻĐ·Đ”Ń‚Ń‚Ń–Đș. Đ•ĐœĐŽŃ– Đ¶ĐžĐœĐ°Đ»Ń‹ŃÒ›Đ° жарты сДĐșŃƒĐœĐŽ та ĐșĐ”ŃˆŃ–ĐșпДĐčсіз." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ĐąĐŸĐżŃ‚Ń‹Ò› Ò›ĐŸÒŁŃ‹Ń€Đ°ŃƒÒ“Đ° Đ±Ń–Ń€Đ”Ńƒ Ò›ĐŸŃŃ‹Đ»Ò“Đ°ĐœĐŽĐ° ĐœĐ”ĐŒĐ”ŃĐ” ĐŸĐŽĐ°Đœ ŃˆŃ‹Ò“Ń‹Đż ĐșДтĐșĐ”ĐœĐŽĐ”, ĐČĐžĐŽĐ”ĐŸĐżĐ»ĐžŃ‚ĐșĐ°Đ»Đ°Ń€ĐŽĐ°Ò“Ń‹ Đ°ŃƒŃ‹ŃŃ‹ĐŒ Đ°ĐœĐžĐŒĐ°Ń†ĐžŃŃŃ‹Đœ Ń‚ÒŻĐ·Đ”Ń‚Ń‚Ń–Đș. Đ”ĐŸŃŃ‹ÒŁŃ‹Đ·ĐŽŃ‹ÒŁ Ń‚ÒŻŃ€Ń– ĐșÓ©Ń€Ń–ĐœĐłĐ”ĐœĐŽĐ”, Ó™Đ»Đ”ŃƒĐŒĐ”Ń‚Ń‚Ń–Đș жДлі тірілЎі ĐŽĐ”ĐłĐ”Đœ сөз." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Чат Ń‚Đ°Ò›Ń‹Ń€Ń‹Đ±Ń‹ĐœĐŽĐ°Ò“Ń‹ ĐżŃ€ĐŸŃ„ĐžĐ»Ń–ÒŁŃ–Đ·ĐŽŃ–ÒŁ ŃŃƒŃ€Đ”Ń‚Ń–Đœ ĐœĐ”ĐŒĐ”ŃĐ” Ń‚ĐŸĐż аĐČĐ°Ń‚Đ°Ń€Ń‹Đœ басып, чат ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€Ń–ĐœĐ” Đ¶Ń‹Đ»ĐŽĐ°ĐŒ ĐșірД аласыз ĐœĐ”ĐŒĐ”ŃĐ” ŃĐŸĐ» Ń‡Đ°Ń‚Ń‚Đ°Ò“Ń‹ ĐșÓ©Ń€Ń–Đ»ĐŒĐ”ĐłĐ”Đœ ŃŃ‚ĐŸŃ€ĐžŃŃ‚Đ”Ń€ĐŽŃ– ĐșөрД аласыз. Đ Đ°Ò›ĐŒĐ”Ń‚, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/km-KH/messages.json b/_locales/km-KH/messages.json index 5d79ffc49c..2f21d7537b 100644 --- a/_locales/km-KH/messages.json +++ b/_locales/km-KH/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "បញ្ហាទិន្នន័យ", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "áž˜áž¶áž“áž”áž‰áŸ’áž áž¶áž˜ážŒáž›ážŠáŸ’áž‹áž¶áž“áž‘áž·áž“áŸ’áž“áž“áŸáž™áž”áž¶áž“áž€ážŸážážĄážŸáž„áŸ” ážąáŸ’áž“áž€ážąáž¶áž…áž…áž˜áŸ’áž›áž„áž”áž‰áŸ’áž áž¶áž“áŸáŸ‡ ហសយទាក់ទងផ្នែកជំនវយរបស់ Signal ážČ្យជវយដោះស្រាយបញ្ហា។ áž”áŸ’ážšážŸáž·áž“áž”ážŸážąáŸ’áž“áž€ážáŸ’ážšážŒážœáž€áž¶ážšáž”áŸ’ážšážŸ Signal ភ្លាមៗ ážąáŸ’áž“áž€ážąáž¶áž…áž›áž»áž”áž‘áž·áž“áŸ’áž“áž“áŸáž™ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ áž ážŸáž™áž…áž¶áž”áŸ‹áž•áŸ’ážážŸáž˜ážĄážŸáž„ážœáž·áž‰áŸ”\n\nទាក់ទងផ្នែកជំនវយដោយចឌលទៅកាន់៖ {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "áž›áž»áž”áž‘áž·áž“áŸ’áž“áž“áŸáž™áž‘áž¶áŸ†áž„ážąážŸáŸ‹ áž“áž·áž„áž…áž¶áž”áŸ‹áž•áŸ’ážážŸáž˜ážĄážŸáž„ážœáž·áž‰", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "លុបទិន្នន័យ áž“áž·áž„áž…áž¶áž”áŸ‹áž•áŸ’ážážŸáž˜ážĄážŸáž„ážœáž·áž‰", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "áž›áž»áž”áž‘áž·áž“áŸ’áž“áž“áŸáž™áž‘áž¶áŸ†áž„ážąážŸáŸ‹áž‡áž¶ážšáŸ€áž„ážšáž ážŒážážŹ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ប្រវត្តិសារ áž“áž·áž„áž˜áŸážŒáŸ€áž‘áž¶áŸ†áž„ážąážŸáŸ‹ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž“ážčងត្រឌវបានលុបជារៀងរហឌតពឞឧបករណ៍នេះ។ ឱ្នកនážčáž„ážąáž¶áž…áž”áŸ’ážšážŸ Signal នៅលសឧបករណ៍នេះ áž”áž“áŸ’áž‘áž¶áž”áŸ‹áž–ážžáž—áŸ’áž‡áž¶áž”áŸ‹ážœáž¶ážĄážŸáž„ážœáž·áž‰áŸ” ការធ្វសបែបនេះនážčáž„áž˜áž·áž“áž›áž»áž”áž‘áž·áž“áŸ’áž“áž“áŸáž™ážŽáž¶áž˜ážœáž™áž…áŸáž‰áž–ážžáž‘ážŒážšážŸáž–áŸ’áž‘ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž‘áŸáŸ”", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "áž€áŸ†ážŽáŸ‚áž“áŸƒáž˜ážŒáž›ážŠáŸ’áž‹áž¶áž“áž‘áž·áž“áŸ’áž“áž“áŸáž™ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž˜áž·áž“ážáŸ’ážšážŒážœáž‚áŸ’áž“áž¶áž“ážčងកំណែរបស់ Signal នេះទេ។ ážáŸ’ážšážŒážœáž”áŸ’ážšáž¶áž€ážŠážáž¶ážąáŸ’áž“áž€áž€áŸ†áž–áž»áž„áž”ážŸáž€áž€áŸ†ážŽáŸ‚ážáŸ’áž˜ážžáž”áŸ†áž•áž»ážáž“áŸƒ Signal áž“áŸ…áž›ážŸáž€áž»áŸ†áž–áŸ’áž™ážŒáž‘áŸážšážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áŸ”", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ážŻáž€ážŸáž¶ážš", @@ -300,6 +316,70 @@ "messageformat": "ការជជែក", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "áž˜áž¶áž“ážąáŸ’ážœážžáž˜ážœáž™áž˜áž·áž“áž”áŸ’ážšáž€áŸ’ážšážážžáž‡áž¶áž˜ážœáž™ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ áž–áŸ’ážšáŸ„áŸ‡ážœáž¶áž›áŸ‚áž„áž€áŸ†ážŽážáŸ‹áž‡áž¶ážˆáŸ’áž˜áŸ„áŸ‡ážšáž”ážŸáŸ‹áž‚ážŽáž“ážžážąáŸ’áž“áž€áž‘áŸ€ážáž ážŸáž™áŸ” ážąáŸ’áž“áž€ážąáž¶áž…ážŸáž¶áž€áž›áŸ’áž”áž„ និងកំណត់វាម្តងទៀត ážŹáž‡áŸ’ážšážŸážŸážšážŸážŸážˆáŸ’áž˜áŸ„áŸ‡ážáŸ’áž˜ážžáž˜ážœáž™áŸ”", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ážŠáŸ„áŸ‡ážŸáŸ’ážšáž¶áž™áž„ážĄážŒážœáž“áŸáŸ‡", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "áž˜áž¶áž“ážąáŸ’ážœážžáž˜ážœáž™áž˜áž·áž“áž”áŸ’ážšáž€áŸ’ážšážážžáž‡áž¶áž˜ážœáž™áž€ážŒážŠ QR áž“áž·áž„ážáŸ†ážŽážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ វាលែងមានសុពលភាពទៀតហសយ។ áž”áž„áŸ’áž€ážŸážážáŸ†ážŽážáŸ’áž˜ážžáž˜ážœáž™ážŠážŸáž˜áŸ’áž”ážžáž…áŸ‚áž€ážšáŸ†áž›áŸ‚áž€áž‡áž¶áž˜ážœáž™ážąáŸ’áž“áž€ážŠáž‘áŸƒáŸ”", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ážŠáŸ„áŸ‡ážŸáŸ’ážšáž¶áž™áž„ážĄážŒážœáž“áŸáŸ‡", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "បង្ហាញផ្ទាំង", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "លាក់ផ្ទាំង", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "áž”áž‰áŸ’áž áž¶áž˜ážœáž™áž”áž¶áž“áž€ážŸážážĄážŸáž„", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} áž˜áž·áž“áž‘áž¶áž“áŸ‹ážąáž¶áž“", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "áž”áž¶áž“ážŸáž˜áŸ’áž‚áž¶áž›áŸ‹ážáž¶áž˜áž·áž“áž‘áž¶áž“áŸ‹ážąáž¶áž“", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ការជជែក", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ការហៅ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ážšážżáž„ážšáŸ‰áž¶ážœ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ការកំណត់", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ážŠáŸ†ážĄážŸáž„ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ប្រវត្តិរឌប", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ត្រលប់ក្រោយ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ការជជែកទាំងនេះត្រឌវបានទុកក្នុងបណ្ណសារ ហសយនážčáž„áž”áž„áŸ’áž áž¶áž‰áž€áŸ’áž“áž»áž„áž”áŸ’ážšážąáž”áŸ‹ážŸáž¶ážš ážáŸ‚áž–áŸáž›ážŽáž¶ážŠáŸ‚áž›ážąáŸ’áž“áž€áž‘áž‘ážœáž›áž”áž¶áž“ážŸáž¶ážšážáŸ’áž˜ážžáž”áŸ‰áž»ážŽáŸ’ážŽáŸ„áŸ‡áŸ”", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ហៅ យ៉ាងណាក៏ដោយ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ចឌលរវមតែម្តង", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "បន្តការហៅ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "លេខសុវត្ថិភាពកំពុងត្រឌវបានធ្វសបច្ចុប្បន្នភាព។", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "សិក្សាបន្ថែម", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "លេខសុវត្ថិភាពពឞមុន", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "លេខសុវត្ថិភាពបន្ទាប់", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "កំណែលេខសុវត្ថិភាព {index,number} នៃ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "សម្គាល់ថាបានផ្ទៀងផ្ទាត់", @@ -663,33 +747,41 @@ "messageformat": "ážŸáž˜áŸ’ážąáž¶ážáž€áž¶ážšáž•áŸ’áž‘áŸ€áž„áž•áŸ’áž‘áž¶ážáŸ‹", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "ážŠážŸáž˜áŸ’áž”ážžáž•áŸ’áž‘áŸ€áž„áž•áŸ’áž‘áž¶ážáŸ‹áž€áž¶ážšážąáŸŠážžáž“áž‚áŸ’ážšážžáž”áž‘áž¶áŸ†áž„ážŸáž„ážáž¶áž„áž‡áž¶áž˜ážœáž™ {name} សឌមប្រៀបធៀបលេខខាងលសជាមវយឧបករណ៍របស់ពវកគេ។ áž–ážœáž€áž‚áŸáž€áŸážąáž¶áž…ážŸáŸ’áž‚áŸ‚áž“áž€ážŒážŠážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ážŠáŸ„áž™áž”áŸ’ážšážŸáž§áž”áž€ážšážŽáŸážšáž”ážŸáŸ‹áž–ážœáž€áž‚áŸáž•áž„ážŠáŸ‚ážšáŸ”", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ស្វែងយល់បន្ថែម", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "ážŠážŸáž˜áŸ’áž”ážžáž•áŸ’áž‘áŸ€áž„áž•áŸ’áž‘áž¶ážáŸ‹áž€áž¶ážšážąáŸŠážžáž“áž‚áŸ’ážšážžáž”áž‘áž¶áŸ†áž„ážŸáž„ážáž¶áž„áž‡áž¶áž˜ážœáž™ {name} សឌមផ្គឌផ្គងកាតពណ៌ខាងលសជាមវយឧបករណ៍របស់ពវកគេ ហសយប្រៀបធៀបលេខ។ ប្រសិនបសលេខទាំងនេះមិនត្រឌវគ្នាទេ សឌមសាកល្បងលេខសុវត្ថិភាពគឌផ្សេងទៀត។ មានតែមវយគឌប៉ុណ្ណោះដែលត្រឌវផ្គឌផ្គង។", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "ážŠážŸáž˜áŸ’áž”ážžáž•áŸ’áž‘áŸ€áž„áž•áŸ’áž‘áž¶ážáŸ‹áž€áž¶ážšážąáŸŠážžáž“áž‚áŸ’ážšážžáž”áž‘áž¶áŸ†áž„ážŸáž„ážáž¶áž„áž‡áž¶áž˜ážœáž™ {name} សឌមប្រៀបធៀបលេខខាងលសជាមវយឧបករណ៍របស់ពវកគេ។ áž–ážœáž€áž‚áŸáž€áŸážąáž¶áž…ážŸáŸ’áž‚áŸ‚áž“áž€ážŒážŠážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ážŠáŸ„áž™áž”áŸ’ážšážŸáž§áž”áž€ážšážŽáŸážšáž”ážŸáŸ‹áž–ážœáž€áž‚áŸáž•áž„ážŠáŸ‚ážšáŸ”", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ការផ្លាស់ប្តឌរចំពោះលេខសុវត្ថិភាព", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "លេខសុវត្ថិភាពកំពុងត្រឌវបានធ្វសបច្ចុប្បន្នភាពក្នុងរយៈពេលផ្លាស់ប្តឌរ ážŠážŸáž˜áŸ’áž”ážžáž”ážŸáž€áž˜áž»ážáž„áž¶ážšážŻáž€áž‡áž“áž—áž¶áž–áž“áž¶áž–áŸáž›ážáž¶áž„áž˜áž»ážáž“áŸ…áž€áŸ’áž“áž»áž„ Signal។", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ដសម្បឞផ្ទៀងផ្ទាត់លេខសុវត្ថិភាព ážŸážŒáž˜áž•áŸ’áž‚ážŒáž•áŸ’áž‚áž„áž€áž¶ážáž–ážŽáŸŒáž‡áž¶áž˜ážœáž™áž§áž”áž€ážšážŽáŸáž“áŸƒážˆáŸ’áž˜áŸ„áŸ‡áž‘áŸ†áž“áž¶áž€áŸ‹áž‘áŸ†áž“áž„ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áŸ” ប្រសិនបសលេខទាំងនេះមិនត្រឌវគ្នាទេ សឌមសាកល្បងលេខសុវត្ថិភាពគឌផ្សេងទៀត។ មានតែមវយគឌប៉ុណ្ណោះដែលត្រឌវផ្គឌផ្គង។", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ត្រឌវការជំនវយ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "យល់ហសយ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "លេខសុវត្ថិភាពមវយនážčáž„ážáŸ’ážšážŒážœáž”áž¶áž“áž”áž„áŸ’áž€ážŸážážĄážŸáž„áž‡áž¶áž˜ážœáž™áž”áž»áž‚áŸ’áž‚áž›áž“áŸáŸ‡ áž”áž“áŸ’áž‘áž¶áž”áŸ‹áž–ážžážąáŸ’áž“áž€áž•áŸ’áž‰ážŸážŸáž¶ážšáž‘áŸ…ážœáž·áž‰áž‘áŸ…áž˜áž€áž‡áž¶áž˜ážœáž™áž‚áŸáŸ”", @@ -1267,10 +1359,6 @@ "messageformat": "áž”áž„áŸ’áž áž¶áž‰ážŻáž€ážŸáž¶ážšáž˜áŸážŒáž¶ážáŸ’áž˜ážžáŸ—", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "ážŠážŸáž˜áŸ’áž”ážžáž•áŸ’áž‘áŸ€áž„áž•áŸ’áž‘áž¶ážáŸ‹ážŸáž»ážœážáŸ’ážáž·áž—áž¶áž–áž“áŸƒáž€áž¶ážšážąáŸŠážžáž“áž‚áŸ’ážšážžáž”áž‘áž¶áŸ†áž„ážŸáž„ážáž¶áž„ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž‡áž¶áž˜ážœáž™ {name} សឌមប្រៀបធៀបលេខខាងលសជាមវយឧបករណ៍របស់ពវកគេ។ áž–ážœáž€áž‚áŸáž€áŸážąáž¶áž…ážŸáŸ’áž‚áŸ‚áž“áž€ážŒážŠ QR ខាងលសផងដែរ។", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ážąáŸ’áž“áž€áž˜áž·áž“áž‘áž¶áž“áŸ‹áž”áž¶áž“áž•áŸ’ážáŸ„áŸ‡áž”áŸ’ážážŒážšážŸáž¶ážšážŽáž¶áž˜ážœáž™áž‡áž¶áž˜ážœáž™áž›áŸážáž‘áŸ†áž“áž¶áž€áŸ‹áž‘áŸ†áž“áž„áž“áŸáŸ‡áž‘áŸáŸ” áž›áŸážážŸáž»ážœážáŸ’ážáž·áž—áž¶áž–ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž‡áž¶áž˜ážœáž™áž‚áŸ នážčងមានបន្ទាប់ពឞផ្ញសសារដំបឌង។" }, @@ -1334,17 +1422,17 @@ "messageformat": "ព័ត៌មាន", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "លុប", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "លុបសារ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "áž›áž»áž”áž€áž¶ážšáž‡áž‡áŸ‚áž€ážŹ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "áž›áž»áž”ážŸáž¶ážšážŹ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ការជជែកនេះនážčងត្រឌវលុបចេញពឞឧបករណ៍នេះ។", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "សារនៅក្នុងការជជែកនេះនážčងត្រឌវបានលុបចេញពឞឧបករណ៍នេះ។ ážąáŸ’áž“áž€áž“áŸ…ážáŸ‚ážąáž¶áž…ážŸáŸ’ážœáŸ‚áž„ážšáž€áž€áž¶ážšáž‡áž‡áŸ‚áž€áž“áŸáŸ‡áž”áž¶áž“ áž”áž“áŸ’áž‘áž¶áž”áŸ‹áž–ážžážąáŸ’áž“áž€áž›áž»áž”ážŸáž¶ážšáž ážŸáž™áŸ”", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ចាកចេញពឞក្រុម", @@ -1438,6 +1526,14 @@ "messageformat": "áž”áŸ’ážšážœážáŸ’ážáž·ážŸáž¶ážšážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ážŸáž˜áŸ’ážšáž¶áž”áŸ‹áž€áž¶ážšáž‡áž‡áŸ‚áž€áž‘áž¶áŸ†áž„áž–ážžážšážáŸ’ážšážŒážœáž”áž¶áž“áž”áž‰áŸ’áž…ážŒáž›áž‚áŸ’áž“áž¶áž“áŸ…áž‘ážžáž“áŸáŸ‡áŸ”", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} ជាលេខរបស់ {conversationTitle}។ ážąáŸ’áž“áž€áž‘áž¶áŸ†áž„áž–ážžážšáž‡áž¶ážŸáž˜áž¶áž‡áž·áž€áž“áŸƒ {sharedGroup}។", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} ជាលេខរបស់ {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "រឌបភាពតឌចៗនៃរឌបភាពពឞសារដែលបានដកស្រង់", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ហៅម្តងទៀត", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ចាប់ផ្តសមការហៅ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ចឌលរវមការហៅ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "áž˜ážžáž€áŸ’ážšážŒáž áŸ’ážœážŒáž“ážáŸ’ážšážŒážœáž”áž¶áž“áž”áž·áž‘ážŸáŸ†ážĄáŸáž„ážŠáŸ„áž™ážŸáž¶ážšáž˜áž¶áž“áž˜áž“áž»ážŸáŸ’ážŸáž…áŸ’ážšážŸáž“áž…ážŒáž›ážšážœáž˜áž€áŸ’áž“áž»áž„áž€áž¶ážšáž áŸ…", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ការជឌនដំណážčáž„ážąáŸ†áž–ážžáž€áž¶ážšáž áŸ…", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ការហៅពេញ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "កាមេរ៉ា", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ចឌលរវម", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ចាប់ផ្ដសម", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ការហៅពេញហសយ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "កាមេរ៉ាត្រឌវបានបិទ", @@ -1621,10 +1725,6 @@ "messageformat": "បសកកាមេរ៉ា", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "áž”áž·áž‘ážŸáŸ†ážĄáŸáž„", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "មឞក្រឌហ្វឌនត្រឌវបានបិទ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "áž”ážŸáž€ážŸáŸ†ážĄáŸáž„áž˜ážžáž€áŸ’ážšážŒáž áŸ’ážœážŒáž“", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ចែករំលែក", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ការបង្ហាញត្រឌវបានបិទ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ឈប់បង្ហាញ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "រោទិ៍", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ក្រុមធំពេក áž€áŸ’áž“áž»áž„áž€áž¶ážšáž áŸ…ážąáŸ’áž“áž€áž…ážŒáž›ážšážœáž˜áŸ”", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "áž”ážŸáž€ážŸáŸ†ážĄáŸáž„ážšáŸ„áž‘áŸ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "áž”áž·áž‘ážŸáŸ†ážĄáŸáž„ážšáŸ„áž‘áŸ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "áž”ážŸáž€ážŸáŸ†ážĄáŸáž„ážšáŸ„áž‘áŸ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ជម្រសសច្រសនទៀត", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ឱ្នក", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "áž€áž¶áž˜áŸážšáŸ‰áž¶ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž”áž¶áž“áž”áž·áž‘", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "មសលលេខសុវត្ថិភាព", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "សារ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "មសលលេខសុវត្ថិភាព", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "áž˜áž·áž“ážąáž¶áž…ážŸáŸ’ážšáž„áŸ‹ážšáž€áž›áŸážáž‘ážŒážšážŸáž–áŸ’áž‘áž”áž¶áž“áŸ” ážŸážŒáž˜áž–áž·áž“áž·ážáŸ’áž™áž˜ážŸáž›ážŸáŸážœáž¶ážąáŸŠážžáž“áž’ážșážŽáž·ážážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ រវចព្យាយាមម្តងទៀត។", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "áž€áž¶ážšáž€áŸ‚ážŸáž¶ážšážąáž¶áž…áž’áŸ’ážœážŸáž”áž¶áž“ážáŸ‚áž€áŸ’áž“áž»áž„ážšáž™áŸˆáž–áŸáž› 3 áž˜áŸ‰áŸ„áž„áž‚áž·ážáž…áž¶áž”áŸ‹áž–ážžáž–áŸáž›ážŠáŸ‚áž›ážąáŸ’áž“áž€áž”áž¶áž“áž•áŸ’áž‰ážŸážŸáž¶ážšáž“áŸáŸ‡áž”áŸ‰áž»ážŽáŸ’ážŽáŸ„áŸ‡áŸ”", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "áž€áž¶ážšáž€áŸ‚ážŸáž¶ážšážąáž¶áž…áž’áŸ’ážœážŸáž”áž¶áž“ážáŸ‚áž€áŸ’áž“áž»áž„ážšáž™áŸˆáž–áŸáž› 24 áž˜áŸ‰áŸ„áž„áž‚áž·ážáž…áž¶áž”áŸ‹áž–ážžáž–áŸáž›ážŠáŸ‚áž›ážąáŸ’áž“áž€áž”áž¶áž“áž•áŸ’áž‰ážŸážŸáž¶ážšáž“áŸáŸ‡áž”áŸ‰áž»ážŽáŸ’ážŽáŸ„áŸ‡áŸ”", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "សារនេះត្រឌវបានលុប។", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ážŻáž€ážŸáž¶ážšáž—áŸ’áž‡áž¶áž”áŸ‹áž’áŸ†áž–áŸáž€áž˜áž·áž“ážąáž¶áž…áž”áž„áŸ’áž áž¶áž‰áž”áž¶áž“áŸ”", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ážŻáž€ážŸáž¶ážšáž—áŸ’áž‡áž¶áž”áŸ‹áž˜ážœáž™áž…áŸ†áž“ážœáž“áž˜áž¶áž“áž‘áŸ†áž áŸ†áž’áŸ†áž–áŸáž€áž˜áž·áž“ážąáž¶áž…áž”áž„áŸ’áž áž¶áž‰áž”áž¶áž“áŸ”", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "áž˜áž·áž“ážąáž¶áž…áž”ážŸáž€áž–áŸážáŸŒáž˜áž¶áž“áž›áž˜áŸ’ážąáž·ážážąáŸ†áž–ážžáž€áž¶ážšáž”ážšáž·áž…áŸ’áž…áž¶áž‚áž”áž¶áž“áž‘áŸ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "សម្រាប់តែ Signal បេតាប៉ុណ្ណោះ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "áž€áž¶ážšáž€áŸ‚ážŸáž¶ážšáž˜áž¶áž“ážŸáž˜áŸ’ážšáž¶áž”áŸ‹ážáŸ‚ážąáŸ’áž“áž€áž”áŸ’ážšážŸ Signal បេតាប៉ុណ្ណោះ។ áž”áŸ’ážšážŸáž·áž“áž”ážŸážąáŸ’áž“áž€áž€áŸ‚ážŸáž¶ážš áž˜áž¶áž“ážáŸ‚ážąáŸ’áž“áž€ážŠáŸ‚áž›áž˜áž¶áž“áž€áŸ†ážŽáŸ‚áž…áž»áž„áž€áŸ’ážšáŸ„áž™áž”áŸ†áž•áž»ážáž“áŸƒ Signal áž”áŸážáž¶áž”áŸ‰áž»ážŽáŸ’ážŽáŸ„áŸ‡áž‘ážŸáž”ážąáž¶áž…áž˜ážŸáž›ážœáž¶ážƒážŸáž‰áŸ”", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "កែសារ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "áž”áŸ’ážšážŸáž·áž“áž”ážŸážąáŸ’áž“áž€áž€áŸ‚ážŸáž¶ážš áž˜áž¶áž“ážáŸ‚ážąáŸ’áž“áž€ážŠáŸ‚áž›áž˜áž¶áž“áž€áŸ†ážŽáŸ‚áž…áž»áž„áž€áŸ’ážšáŸ„áž™áž”áŸ†áž•áž»ážáž“áŸƒ Signal áž”áŸ‰áž»ážŽáŸ’ážŽáŸ„áŸ‡áž‘ážŸáž”ážąáž¶áž…áž˜ážŸáž›ážœáž¶ážƒážŸáž‰áŸ” ពវកគេនážčáž„ážąáž¶áž…áž˜ážŸáž›ážƒážŸáž‰ážáž¶ážąáŸ’áž“áž€áž”áž¶áž“áž€áŸ‚ážŸáž¶ážšáŸ”", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "áž€áž¶ážšáž áŸ…áž…ážŒáž›áž‡áž¶ážœážžážŠáŸážąážŒâ€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "áž€áž¶ážšáž áŸ…áž…áŸáž‰áž‡áž¶ážŸáŸ†ážĄáŸáž„", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "áž€áž¶ážšáž áŸ…áž…áŸáž‰áž‡áž¶ážœážžážŠáŸážąážŒ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} áž€áŸ†áž–áž»áž„áž áŸ…áž˜áž€ážąáŸ’áž“áž€", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "áž€áŸ†áž–áž»áž„áž—áŸ’áž‡áž¶áž”áŸ‹ážĄážŸáž„ážœáž·áž‰â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {មនុស្ស {count,number} នាក់}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "áž€áž¶ážšáž áŸ…áž‡áž¶ážŸáŸ†ážĄáŸáž„", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "បញ្ចប់", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ចាកចេញ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "បានបិទមឞក្រឌហ្វឌន", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "បានបសកមឞក្រឌហ្វឌន", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "áž”áž¶áž“áž”ážŸáž€ážŸáŸ†ážĄáŸáž„ážšáŸ„áž‘áŸ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "áž”áž¶áž“áž”áž·áž‘ážŸáŸ†ážĄáŸáž„ážšáŸ„áž‘áŸ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ការកំណត់", @@ -3468,13 +3668,25 @@ "messageformat": "áž€áž¶ážšáž áŸ…áž–áŸáž‰ážąáŸáž€áŸ’ážšáž„áŸ‹", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "áž”áŸ’ážŠážŒážšâ€‹áž‘áŸ…â€‹áž‘áž·ážŠáŸ’áž‹áž—áž¶áž–â€‹áž€áŸ’ážšážĄáž¶", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ផ្លាស់ប្តឌរទិដ្ឋភាព", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "áž”áŸ’ážážŒážšáž‘áŸ…áž‘áž·ážŠáŸ’áž‹áž—áž¶áž–ážąáŸ’áž“áž€áž“áž·áž™áž¶áž™", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "áž‘áž·ážŠáŸ’áž‹áž—áž¶áž–áž€áŸ’ážšážĄáž¶", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ទិដ្ឋភាពរបារចំហៀង", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ទិដ្ឋភាពវាគ្មិន", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "បានផ្លាស់ប្តឌរទិដ្ឋភាព", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "បិទការហៅ", @@ -3576,6 +3788,14 @@ "messageformat": "យល់ព្រម", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "áž˜áž·áž“ážąáž¶áž…áž€áŸ‚ážŸáž¶ážšáž”áž¶áž“áž‘áŸ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ážŸáž¶ážšáž“áŸáŸ‡ážąáž¶áž…áž€áŸ‚áž”áž¶áž“ážáŸ‚ {max,number} ដងប៉ុណ្ណោះ។", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ážŸážŒáž˜ážąáž—áŸáž™áž‘áŸ„ážŸ តំណ sgnl:// នោះមិនសមហេតុផលទេ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸ", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "áž˜áž¶áž“ážąáŸ’ážœážžáž˜ážœáž™áž˜áž·áž“áž”áŸ’ážšáž€áŸ’ážšážážžáž‡áž¶áž˜ážœáž™ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ áž–áŸ’ážšáŸ„áŸ‡ážœáž¶áž›áŸ‚áž„áž€áŸ†ážŽážáŸ‹áž‡áž¶ážˆáŸ’áž˜áŸ„áŸ‡ážšáž”ážŸáŸ‹áž‚ážŽáž“ážžážąáŸ’áž“áž€áž‘áŸ€ážáž ážŸáž™áŸ”", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "áž›áž»áž”ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "áž”áž„áŸ’áž€ážŸážážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸáž”áŸ’ážšáž¶ážŸáŸ‹", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "កឌដ QR ឬតំណ", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážáŸ’ážšážŒážœáž€áŸ†ážŽážáŸ‹ážĄážŸáž„ážœáž·áž‰", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ážáŸ†ážŽážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážáŸ’ážšážŒážœáž€áŸ†ážŽážáŸ‹ážĄážŸáž„ážœáž·áž‰", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "áž…áŸ‚áž€ážšáŸ†áž›áŸ‚áž€ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážšáž”ážŸáŸ‹ážąáŸ’áž“áž€", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "áž›áž»áž”ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ការធ្វសបែបនេះនážčáž„áž›áž»áž”ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ ហសយធ្វសážČáŸ’áž™ážąáŸ’áž“áž€áž”áŸ’ážšážŸáž•áŸ’ážŸáŸáž„áž‘áŸ€ážáž™áž€ážœáž¶áž‘áŸ…áž”áŸ’ážšážŸáž”áž¶áž“áŸ” ážážŸážąáŸ’áž“áž€áž…áŸ’áž”áž¶ážŸáŸ‹ážąážáŸ‹?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ការធ្វសបែបនេះនážčáž„áž›áž»áž”ážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž…áŸáž‰ ហសយបិទកឌដ QR áž“áž·áž„ážáŸ†ážŽážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áŸ” “{username}” នážčងមានសម្រាប់ážČáŸ’áž™ážąáŸ’áž“áž€áž•áŸ’ážŸáŸáž„áž‘áŸ€ážáž‘áž¶áž˜áž‘áž¶ážšáž™áž€áŸ” ážážŸážąáŸ’áž“áž€áž”áŸ’ážšáž¶áž€ážŠážŹáž‘áŸ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ឱ្នកនážčáž„áž˜áž·áž“ážąáž¶áž…áž…áŸ‚áž€ážšáŸ†áž›áŸ‚áž€ ážŹáž˜ážŸáž›ážšážżáž„ážšáŸ‰áž¶ážœáž”áž¶áž“áž‘áŸ€ážáž‘áŸáŸ” áž”áž…áŸ’áž…áž»áž”áŸ’áž”áž“áŸ’áž“áž—áž¶áž–ážšážżáž„ážšáŸ‰áž¶ážœážŠáŸ‚áž›ážąáŸ’áž“áž€áž”áž¶áž“áž…áŸ‚áž€ážšáŸ†áž›áŸ‚áž€áž“áž¶áž–áŸáž›ážáŸ’áž˜ážžáŸ—áž“áŸáŸ‡áž€áŸáž“ážčងត្រឌវបានលុបចោលផងដែរ។", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ភាសា", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ភាសា", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ភាសាប្រព័ន្ធ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ស្វែងរកភាសា", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "គ្មានលទ្ធផលសម្រាប់ “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "កំណត់", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ចាប់ផ្តសម Signal ážĄážŸáž„ážœáž·áž‰ážŠážŸáž˜áŸ’áž”ážžážąáž“áž»ážœážáŸ’áž", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ដសម្បឞផ្លាស់ប្តឌរភាសា áž€áž˜áŸ’áž˜ážœáž·áž’ážžáž“áŸáŸ‡ážáŸ’ážšážŒážœáž…áž¶áž”áŸ‹áž•áŸ’ážážŸáž˜ážĄážŸáž„ážœáž·áž‰áŸ”", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "áž…áž¶áž”áŸ‹áž•áŸ’ážŠážŸáž˜ážĄážŸáž„ážœáž·áž‰", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ážŠáŸ†ážĄážŸáž„áž€áŸ†ážŽáŸ‚áž‘áŸ… {version} ដែលមាន", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "áž˜áž¶áž“áž”áž‰áŸ’áž áž¶áž˜ážœáž™áž€ážŸážážĄážŸáž„áž“áŸ…áž–áŸáž›ážšáž€áŸ’ážŸáž¶áž‘áž»áž€áž€áž¶ážšáž€áŸ†ážŽážáŸ‹ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áŸ” សឌមព្យាយាមម្តងទៀត។", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "សារ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ស្តាយល៍ជាច្រសនទៀត", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "áž€áŸ†ážŽážáŸ‹ážĄážŸáž„ážœáž·áž‰", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "បញ្ចប់", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "áž–ážŽáŸŒážáŸ†ážŽážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸ, {index,number} នៃ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "áž”áŸ’ážšážŸáž·áž“áž”ážŸážąáŸ’áž“áž€áž€áŸ†ážŽážáŸ‹áž€ážŒážŠ QR ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ážĄážŸáž„ážœáž·áž‰ កឌដ QR áž“áž·áž„ážáŸ†ážŽážŠáŸ‚áž›áž˜áž¶áž“ážŸáŸ’ážšáž¶áž”áŸ‹ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž“ážčងមិនដំណសរការទៀតទេ។", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "áž€áŸ†ážŽážáŸ‹ážáŸ†ážŽážĄážŸáž„ážœáž·áž‰â€Š", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "កឌដ QR និងតំណមិនត្រឌវបានកំណត់ទេ។ ážŸážŒáž˜áž–áž·áž“áž·ážáŸ’áž™áž˜ážŸáž›ážŸáŸážœáž¶ážąáŸŠážžáž“áž’ážșážŽáž·ážážšáž”ážŸáŸ‹ážąáŸ’áž“áž€ រវចព្យាយាមម្តងទៀត។", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "áž”áž„áŸ’áž€ážŸážážˆáŸ’áž˜áŸ„áŸ‡ážąáŸ’áž“áž€áž”áŸ’ážšážŸ Signal របស់ឱ្នក", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "បញ្ជឌនម្តងទៀត", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "សកម្មភាពច្រសនទៀត", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ការហៅ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ការហៅថ្មឞ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ការហៅថ្មឞ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "សកម្មភាពច្រសនទៀត", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "លុបប្រវត្តិហៅទឌរសព្ទ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "áž›áž»áž”áž”áŸ’ážšážœážáŸ’ážáž·áž áŸ…áž‘ážŒážšážŸáž–áŸ’áž‘ážŹ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "វានážčáž„áž›áž»áž”áž”áŸ’ážšážœážáŸ’ážáž·áž áŸ…áž‘ážŒážšážŸáž–áŸ’áž‘áž‘áž¶áŸ†áž„ážąážŸáŸ‹áž‡áž¶ážąáž…áž·áž“áŸ’ážáŸ’ážšáŸƒáž™áŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ážŸáž˜áŸ’ážąáž¶áž", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "áž”áž¶áž“ážŸáž˜áŸ’ážąáž¶ážáž”áŸ’ážšážœážáŸ’ážáž·áž áŸ…", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ចុចដសម្បឞមសល ážŹáž…áž¶áž”áŸ‹áž•áŸ’ážážŸáž˜áž€áž¶ážšáž áŸ…", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ស្វែងរក", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ច្រោះតាមការខកមិនបានទទវល", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "កុងតាក់", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "គ្មានការហៅថ្មឞៗនេះទេ។ ចាប់ផ្តសមដោយហៅទៅមិត្តភក្តិណាម្នាក់។", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "គ្មានលទ្ធផលសម្រាប់ “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ហៅចឌល", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ហៅចេញ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ខកមិនបានទទវល", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ការហៅជាក្រុម", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "គ្មានការសន្ទនាថ្មឞៗនេះទេ។", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "គ្មានលទ្ធផលសម្រាប់ “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {áž€áž¶ážšáž áŸ…áž…áŸáž‰áž‡áž¶ážŸáŸ†ážĄáŸáž„} other {áž€áž¶ážšáž áŸ…áž…ážŒáž›áž‡áž¶ážŸáŸ†ážĄáŸáž„}}} Video {{direction, select, Outgoing {áž€áž¶ážšáž áŸ…áž…áŸáž‰áž‡áž¶ážœážžážŠáŸážąážŒ} other {áž€áž¶ážšáž áŸ…áž…ážŒáž›áž‡áž¶ážœážžážŠáŸážąážŒ}}} Group {{direction, select, Outgoing {ការហៅចេញជាក្រុម} other {ការហៅចឌលជាក្រុម}}} other {{direction, select, Outgoing {ហៅចេញក្រៅ} other {ការហៅចឌល}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {áž€áž¶ážšáž áŸ…áž‡áž¶ážŸáŸ†ážĄáŸáž„ážáž€áž˜áž·áž“áž”áž¶áž“áž‘áž‘ážœáž›} Video {ážáž€ážáž¶áž“áž€áž¶ážšáž áŸ…áž‡áž¶ážœážžážŠáŸážąážŒ} Group {ខកមិនបានទទវលការហៅជាក្រុម} other {ការហៅមិនបានទទវល}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {áž€áž¶ážšáž áŸ…áž‡áž¶ážŸáŸ†ážĄáŸáž„ážŠáŸ‚áž›áž˜áž·áž“áž”áž¶áž“áž†áŸ’áž›ážŸáž™ážáž”} Video {áž€áž¶ážšáž áŸ…áž‡áž¶ážœážžážŠáŸážąážŒážŠáŸ‚áž›áž˜áž·áž“áž”áž¶áž“áž†áŸ’áž›ážŸáž™ážáž”} Group {ការហៅជាក្រុមដែលមិនបានលសក} other {ការហៅដែលមិនបានលសក}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {áž€áž¶ážšáž áŸ…áž‡áž¶ážŸáŸ†ážĄáŸáž„ážŠáŸ‚áž›áž”áž¶áž“áž”ážŠáž·ážŸáŸáž’} Video {áž€áž¶ážšáž áŸ…áž‡áž¶ážœážžážŠáŸážąážŒážŠáŸ‚áž›áž”áž¶áž“áž”ážŠáž·ážŸáŸáž’} Group {ការហៅជាក្រុមដែលបានបដិសេធ} other {ការហៅដែលបានបដិសេធ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number} áž“áž¶áž€áŸ‹áž•áŸ’ážŸáŸáž„áž‘áŸ€ážáž€áŸ†áž–áž»áž„ážœáž¶áž™ážąáž€áŸ’ážŸážšáŸ”}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ឱ្វើដែលថ្មើ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ការកែប្រែបន្តិចបន្តវច ការដោះស្រាយបញ្ហា និងការបង្កសនប្រតិបត្តិការ។ ážŸážŒáž˜ážąážšáž‚áž»ážŽáž…áŸ†áž–áŸ„áŸ‡áž€áž¶ážšáž”áŸ’ážšážŸáž”áŸ’ážšáž¶ážŸáŸ‹ Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "áž€áž¶ážšáž’áŸ’ážœážŸáž”áž…áŸ’áž…áž»áž”áŸ’áž”áž“áŸ’áž“áž—áž¶áž–áž“áŸáŸ‡ážšážœáž˜áž”áž‰áŸ’áž…ážŒáž›áž“ážŒážœáž€áž¶ážšáž€áŸ‚áž›áž˜áŸ’ážąáž˜ážœáž™áž…áŸ†áž“ážœáž“ážŸáž˜áŸ’ážšáž¶áž”áŸ‹áž€áž¶ážšáž áŸ…áž‡áž¶ážŸáŸ†ážĄáŸáž„ áž“áž·áž„áž‡áž¶ážœážžážŠáŸážąážŒ áž“áž·áž„áž€áž¶ážšáž’áŸ’ážœážŸáž”áž…áŸ’áž…áž»áž”áŸ’áž”áž“áŸ’áž“áž—áž¶áž–ážáž·áž…ážážœáž…áž˜ážœáž™áž…áŸ†áž“ážœáž“áž›ážŸážŸáŸ†ážŽáž»áŸ†ážŻáž€ážŸáž¶ážš (ឹរគុណ {linkToGithub}!)។" + "icu:WhatsNew__v6.39--0": { + "messageformat": "áž„ážĄážŒážœáž“áŸáŸ‡ ážąáŸ’áž“áž€ážąáž¶áž…áž•áŸ’áž›áž¶ážŸáŸ‹áž”áŸ’ážážŒážšáž—áž¶ážŸáž¶ážŠáŸ‚áž›ážąáŸ’áž“áž€áž”áž¶áž“áž‡áŸ’ážšážŸážŸážšážŸážŸáž“áŸ…áž€áŸ’áž“áž»áž„ Signal ážŠáŸ„áž™áž˜áž·áž“áž…áž¶áŸ†áž”áž¶áž…áŸ‹áž•áŸ’áž›áž¶ážŸáŸ‹áž”áŸ’ážážŒážšáž€áž¶ážšáž€áŸ†ážŽážáŸ‹áž”áŸ’ážšáž–áŸáž“áŸ’áž’ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž‘áŸ (ការកំណត់ Signal > រឌបរាង > ភាសា)។" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "យសងបានធ្វសបច្ចុប្បន្នភាពរឌបតំណាងការជឌនដំណážčងមវយចំនវនសម្រាប់ក្រុម ដឌចជាពេលដែលមាននរណាម្នាក់ថ្មឞចឌលរវមក្នុងក្រុម។ រឌបតំណាងទាំងនេះជវយážČáŸ’áž™ážąáŸ’áž“áž€áž€áž¶áž“áŸ‹ážáŸ‚áž„áž¶áž™ážŸáŸ’ážšážœáž›áž˜ážŸáž› áž‡áž¶áž–áž·ážŸáŸážŸáž”áŸ’ážšážŸáž·áž“áž”ážŸážąáŸ’áž“áž€áž”áŸ’ážšážŸáž•áŸ’áž‘áŸƒáž–ážŽáŸŒáž„áž„ážčត។ រឌបតំណាងពឞមុនមិនសឌវត្រឌវនážčងផ្ទៃពណ៌ងងážčត។ រឌបតំណាងថ្មឞស័ក្តិសមតែម្តង។" + "icu:WhatsNew__v6.39--1": { + "messageformat": "យសងបានដោះស្រាយបញ្ហានៃការពន្យារពេលខ្លឞមវយ ážŠáŸ‚áž›áž‡ážœáž“áž€áž¶áž›áž€ážŸážážĄážŸáž„áž“áŸ…áž›ážŸáž§áž”áž€ážšážŽáŸ macOS ដោយត្រឌវរង់ចាំបន្តិចនៅពេលចឌលរវមការហៅទឌរសព្ទ។ áž€áž¶ážšáž€áŸ‚áž›áž˜áŸ’ážąáž“áŸáŸ‡áž™áŸ‰áž¶áž„áž áŸ„áž…ážŽáž¶ážŸáŸ‹áž’áŸ’ážœážŸážČáŸ’áž™ážąáŸ’áž“áž€áž…ážŒáž›ážšážœáž˜áž›áŸ‚áž„áž˜áž¶áž“áž›áŸážŸáž‘áŸ€ážáž ážŸáž™ នៅពេលដែលចឌលរវមការប្រជុំយážșតបន្តិច។" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "áž™ážŸáž„áž”áž¶áž“áž€áŸ‚ážŸáž˜áŸ’ážšážœáž›áž“ážŒážœáž€áž¶ážšážŠáž¶áž€áŸ‹áž…áž›áž“áž¶ážŸáž˜áŸ’ážšáž¶áž”áŸ‹áž€áŸ’ážšážĄáž¶ážœážžážŠáŸážąážŒ នៅពេលមាននរណាម្នាក់ចឌលរវម ážŹáž…áž¶áž€áž…áŸáž‰áž–ážžáž€áž¶ážšáž áŸ…áž‡áž¶áž€áŸ’ážšáž»áž˜áŸ” áž“áŸ…áž–áŸáž›ážąáŸ’áž“áž€ážƒážŸáž‰áž˜áž»ážáž˜áž·ážáŸ’ážáž—áž€áŸ’ážáž·ážšáž”ážŸáŸ‹ážąáŸ’áž“áž€áž›áŸáž…ážĄážŸáž„áž“áŸ…áž›ážŸážąáŸáž€áŸ’ážšáž„áŸ‹ នោះហសយជាការប្រសសរសម្រាប់ទំនាក់ទំនងក្នុងបណ្តាញសង្គម។" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "áž„ážĄážŒážœáž“áŸáŸ‡ ážąáŸ’áž“áž€ážąáž¶áž…áž…áž»áž…áž›ážŸážšážŒáž”ážážáž”áŸ’ážšážŒáž áŸ’ážœáž¶áž›áŸ‹ ážŹážšážŒáž”ážáŸ†ážŽáž¶áž„áž€áŸ’ážšáž»áž˜áž“áŸ…áž€áŸ’áž“áž»áž„ážšážŒáž”áž€áŸ’áž”áž¶áž›áž†áž¶áž ដសម្បឞចឌលទៅការកំណត់នៃការជជែកបានឆាប់រហ័ស ážŹáž˜ážŸáž›ážšážżáž„ážšáŸ‰áž¶ážœážŠáŸ‚áž›áž˜áž·áž“áž‘áž¶áž“áŸ‹áž”áž¶áž“ážƒážŸáž‰áž–ážžáž€áž¶ážšáž‡áž‡áŸ‚áž€áž“áŸ„áŸ‡áŸ” ឹរគុណ {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/kn-IN/messages.json b/_locales/kn-IN/messages.json index f78d98c989..958548b12b 100644 --- a/_locales/kn-IN/messages.json +++ b/_locales/kn-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àČĄàł‡àȟàČŸàČŹàł‡àČžàČżàČšàČČàłàČČàČż àČŠàł‹àČ·", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àČĄàł‡àȟàČŸàČŹàł‡àČžàł àČŠàł‹àČ· àČžàȂàČ­àČ”àČżàČžàČżàČŠàł†. àČšàł€àČ”àł àČŠàł‹àČ·àČ”àČšàłàČšàł àČšàȕàČČàČżàČžàČŹàČčàłàČŠàł àČźàČ€àłàČ€àł àȈ àČžàČźàČžàłàČŻàł†àČŻàČšàłàČšàł àČžàȰàČżàČȘàČĄàČżàČžàČČàł àČšàł†àȰàČ”àČŸàȗàČČàł Signal àČŹàł†àȂàČŹàČČàČ”àČšàłàČšàł àČžàȂàČȘàČ°àłàȕàČżàČžàČŹàČčàłàČŠàł. àČšàł€àČ”àł Signal àȅàČšàłàČšàł àȈàȗàČČàł‡ àČŹàČłàČžàČŹàł‡àȕàČżàČŠàłàČŠàČČàłàČČàČż, àČšàČżàČźàłàČź àČĄàł‡àȟàČŸàČ”àČšàłàČšàł àȅàČłàČżàČžàČż àČźàČ°àłàČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČŹàČčàłàČŠàł.\n\nàȇàČČàłàČČàČżàČ—àł† àČ­àł‡àȟàČż àČšàł€àČĄàłàČ” àČźàł‚àČČàȕ àČŹàł†àȂàČŹàČČàČ”àČšàłàČšàł àČžàȂàČȘàČ°àłàȕàČżàČžàČż: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àȎàČČàłàČČàČŸ àČźàČŸàČčàČżàČ€àČżàČŻàČšàłàČšàł àȅàČłàČżàČžàČż àČźàČ°àłàČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČż", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àČĄàł‡àȟàČŸàČ”àČšàłàČšàł àȅàČłàČżàČžàČż àČźàČ€àłàČ€àł àČźàČ°àłàČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČż", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àȎàČČàłàČČàČŸ àČĄàł‡àȟàČŸàČ”àČšàłàČšàł àȶàČŸàČ¶àłàČ”àČ€àČ”àČŸàȗàČż àȅàČłàČżàČžàČŹàł‡àČ•àł†?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àČšàČżàČźàłàČź àȎàČČàłàČČàČŸ àČźàł†àČžàł‡àȜàČżàȂàČ—àł àȇàČ€àČżàČčàČŸàČž àČźàČ€àłàČ€àł àČźàł€àČĄàČżàČŻàČŸàČ”àČšàłàČšàł àȶàČŸàČ¶àłàČ”àČ€àČ”àČŸàȗàČż àȈ àČžàČŸàȧàČšàČŠàČżàȂàČŠ àȅàČłàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČŠàł†. àČžàČŸàȧàČšàČ”àČšàłàČšàł àČźàČ°àłàČČàČżàȂàČ•àł àČźàČŸàČĄàČżàČŠ àČšàȂàČ€àȰ àČšàČżàČźàČ—àł† Signal àȅàČšàłàČšàł àȈ àČžàČŸàȧàČšàČŠàČČàłàČČàČż àČŹàČłàČžàČČàł àČžàČŸàČ§àłàČŻàČ”àČŸàČ—àłàČ€àłàČ€àČŠàł†. àȇàČŠàł àČšàČżàČźàłàČź àČ«àł‹àČšàłâ€ŒàČšàČżàȂàČŠ àČŻàČŸàČ”àłàČŠàł‡ àČĄàł‡àȟàČŸàČ”àČšàłàČšàł àȅàČłàČżàČžàłàČ”àłàČŠàČżàČČàłàČČ.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àČšàČżàČźàłàČź àČĄàł‡àȟàČŸàČŹàł‡àČžàłâ€ŒàČš àȈ àȆàČ”àłƒàČ€àłàČ€àČżàČŻàł Signal àČš àȈ àȆàČ”àłƒàČ€àłàČ€àČżàČ—àł† àČčàłŠàȂàČŠàČżàČ•àł†àČŻàČŸàČ—àłàČ”àłàČŠàČżàČČàłàČČ. àČšàČżàČźàłàČź àȕàȂàČȘàłàČŻàł‚àȟàČ°àłâ€ŒàČšàČČàłàČČàČż Signal àČš àČčàłŠàČšàłàȚàČčàłŠàČž àȆàČ”àłƒàČ€àłàČ€àČżàČŻàČšàłàČšàł àČ€àł†àČ°àł†àČŻàłàČ€àłàČ€àČżàČ°àłàČ”àłàČŠàČšàłàČšàł àȖàČŸàČ€àłàȰàČżàČ—àłŠàČłàČżàČžàČż.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&àČ«àłˆàČČàł", @@ -300,6 +316,70 @@ "messageformat": "àȚàČŸàČŸàłâ€Œâ€Œ àȗàČłàł", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àČšàČżàČźàłàČź àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàłâ€ŒàČšàČČàłàČČàČż àȏàČšàł‹ àČ€àČȘàłàČȘàČŸàȗàČżàČŠàł†, àȅàČŠàČšàłàČšàł àȇàČšàłàČšàł àČźàłàȂàČŠàł† àČšàČżàČźàłàČź àȖàČŸàČ€àł†àČ—àł† àČšàČżàČŻàł‹àȜàČżàČžàČČàČŸàČ—àłàČ”àłàČŠàČżàČČàłàČČ. àČšàł€àČ”àł àČźàČ€àłàČ€àłŠàČźàłàČźàł† àČȘàłàȰàČŻàČ€àłàČšàČżàČžàČż àČčàłŠàȂàČŠàČżàČžàČŹàČčàłàČŠàł àȅàČ„àČ”àČŸ àČčàłŠàČžàČ€àČšàłàČšàł àȆàČŻàłàČ•àł† àČźàČŸàČĄàČŹàČčàłàČŠàł.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àȈàȗàČČàł‡ àČžàȰàČżàČȘàČĄàČżàČžàČż", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àČšàČżàČźàłàČź QR àČ•àł‹àČĄàł àČźàČ€àłàČ€àł àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àČČàČżàȂàČ•àłâ€ŒàČšàČČàłàČČàČż àȏàČšàł‹ àČ€àČȘàłàČȘàČŸàȗàČżàČŠàł†, àȅàČŠàł àȇàČšàłàČšàł àČźàłàȂàČŠàł† àČźàČŸàČšàłàČŻàČ”àČŸàȗàČżàČ°àłàČ”àłàČŠàČżàČČàłàČČ. àȇàČ€àȰàČ°àłŠàȂàČŠàČżàČ—àł† àČčàȂàȚàČżàČ•àłŠàČłàłàČłàČČàł àČčàłŠàČž àČČàČżàȂàČ•àł àȰàȚàČżàČžàČż.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àȈàȗàČČàł‡ àČžàȰàČżàČȘàČĄàČżàČžàČż", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àČŸàłàČŻàČŸàČŹàłâ€ŒàȗàČłàČšàłàČšàł àČ€àł‹àȰàČżàČžàČż", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àČŸàłàČŻàČŸàČŹàłâ€ŒàȗàČłàČšàłàČšàł àČźàČ°àł† àČźàČŸàČĄàČż", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àȒàȂàČŠàł àČŠàł‹àČ· àȉàȂàȟàČŸàȗàČżàČŠàł†", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} àȓàČŠàČżàČČàłàČČ", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àȓàČŠàČżàČČàłàČČ àȎàȂàČŠàł àČ—àłàČ°àłàČ€àČżàČžàČČàČŸàȗàČżàČŠàł†", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àȚàČŸàČŸàłâ€Œâ€Œ àȗàČłàł", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àȕàČ°àł†àȗàČłàł", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àČžàłàČŸàł‹àČ°àł€àČžàł", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àČžàł†àČŸàłàȟàČżàȂàČ—àłâ€ŒàȗàČłàł", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal àȅàČšàłàČšàł àČšàČ”àł€àȕàȰàČżàČžàČż", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àČȘàłàČ°àłŠàČ«àłˆàČČàł", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àČčàČżàȂàČŠàČ•àłàČ•àł†", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àȈ àȚàČŸàČŸàłâ€ŒàȗàČłàČšàłàČšàł àȆàČ°àłàČ•àłˆàČ”àł àČźàČŸàČĄàČČàČŸàȗàČżàČŠàł† àČźàČ€àłàČ€àł àČčàłŠàČž àČźàł†àČžàł‡àČœàłâ€ŒàȗàČłàČšàłàČšàł àČžàłàČ”àł€àȕàȰàČżàČžàČżàČŠàČ°àł† àČźàČŸàČ€àłàȰ àȇàČšàłâ€ŒàČŹàČŸàČ•àłàČžàłâ€ŒàČšàČČàłàČČàČż àȕàČŸàČŁàČżàČžàłàČ€àłàČ€àČŠàł†.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àČčàł‡àȗàČŸàČŠàČ°àł‚ àȕàČ°àł† àČźàČŸàČĄàČż", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àČčàł‡àȗàČŸàČŠàČ°àł‚ àČžàł‡àȰàČż", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àȕàČ°àł†àČŻàČšàłàČšàł àČźàłàȂàČŠàłàČ”àȰàČżàČžàČż", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àČšàČ”àł€àȕàȰàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČżàČŠàł†.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àȇàČšàłàČšàČ·àłàČŸàł àČ€àČżàČłàČżàČŻàČżàȰàČż", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àČčàČżàȂàČŠàČżàČš àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àČźàłàȂàČŠàČżàČš àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àČŻ àȆàČ”àłƒàČ€àłàČ€àČż, {total,number} àČšàČČàłàČČàČż {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àČȘàȰàČżàČ¶àł€àČČàČżàČžàČČàČŸàȗàČżàČŠàł† àȎàȂàČŠàł àČ—àłàČ°àłàČ€àČżàČžàČż", @@ -663,33 +747,41 @@ "messageformat": "àČŠàłƒàČąàł€àȕàȰàČŁàČ”àČšàłàČšàł àČ€àł†àȰàČ”àłàČ—àłŠàČłàČżàČžàČż", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} àȅàČ”àČ°àłŠàȂàČŠàČżàČ—àł† àȎàȂàČĄàł-àČŸàł-àȎàȂàČĄàł àȎàČšàłâ€ŒàČ•àłàȰàČżàČȘàłàȶàČšàł àČŠàłƒàČąàł€àȕàȰàČżàČžàČČàł, àČźàł‡àČČàČżàČš àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àȅàČ”àȰ àČžàČŸàȧàČšàČŠàłŠàȂàČŠàČżàČ—àł† àČčàł‹àČČàČżàČ•àł† àČźàČŸàČĄàČż. àȅàČ”àČ°àł àČ•àł‚àČĄàČŸ àČ€àČźàłàČź àČžàČŸàȧàČšàČŠàłŠàȂàČŠàČżàČ—àł† àČšàČżàČźàłàČź àČ•àł‹àČĄàł àȅàČšàłàČšàł àČžàłàČ•àłàČŻàČŸàČšàł àČźàČŸàČĄàČŹàČčàłàČŠàł.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àȇàČšàłàČšàČ·àłàČŸàł àČ€àČżàČłàČżàČŻàČżàȰàČż", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} àȅàČ”àČ°àłŠàȂàČŠàČżàȗàČżàČš àȎàȂàČĄàł-àČŸàł-àȎàȂàČĄàł àȎàČšàłâ€ŒàČ•àłàȰàČżàČȘàłàȶàČšàł àȅàČšàłàČšàł àČŠàłƒàČąàł€àȕàȰàČżàČžàČČàł, àČźàł‡àČČàČżàČš àȕàČČàČ°àł àȕàČŸàČ°àłàČĄàł àȅàČšàłàČšàł àȅàČ”àȰ àČžàČŸàȧàČšàłŠàȂàČŠàČżàČ—àł† àČčàłŠàȂàČŠàČżàČžàČż àČźàČ€àłàČ€àł àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àČ€àłàČČàČšàł† àČźàČŸàČĄàČż. àȇàČ”àłàȗàČłàł àČčàłŠàȂàČŠàČżàČ•àł†àČŻàČŸàȗàČŠàČżàČŠàłàČŠàČ°àł†, àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àȗàČł àȇàČšàłàČšàłŠàȂàČŠàł àČœàłŠàČ€àł†àČŻàČšàłàČšàł àČȘàłàȰàČŻàČ€àłàČšàČżàČžàČż. àČ•àł‡àČ”àČČ àȒàȂàČŠàł àČœàłŠàČ€àł† àČčàłŠàȂàČŠàČżàČ•àł†àČŻàČŸàȗàČŹàł‡àČ•àł.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} àȅàČ”àČ°àłŠàȂàČŠàČżàČ—àł† àȎàȂàČĄàł-àČŸàł-àȎàȂàČĄàł àȎàČšàłâ€ŒàČ•àłàȰàČżàČȘàłàȶàČšàł àČŠàłƒàČąàł€àȕàȰàČżàČžàČČàł, àČźàł‡àČČàČżàČš àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àȅàČ”àȰ àČžàČŸàȧàČšàČŠàłŠàȂàČŠàČżàČ—àł† àČčàł‹àČČàČżàČ•àł† àČźàČŸàČĄàČż. àȅàČ”àČ°àł àČ•àł‚àČĄàČŸ àČ€àČźàłàČź àČžàČŸàȧàČšàČŠàłŠàȂàČŠàČżàČ—àł† àČšàČżàČźàłàČź àČ•àł‹àČĄàł àȅàČšàłàČšàł àČžàłàČ•àłàČŻàČŸàČšàł àČźàČŸàČĄàČŹàČčàłàČŠàł.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àȗàČłàČżàČ—àł† àČŹàČŠàČČàČŸàČ”àČŁàł†àȗàČłàł", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal àČšàČČàłàČČàČż àČźàłàȂàČŹàČ°àłàČ” àČ—àłŒàČȘàłàČŻàČ€àČŸ àČ«àł€àȚàČ°àłâ€ŒàȗàČłàČšàłàČšàł àČžàČ•àłàȰàČżàČŻàČ—àłŠàČłàČżàČžàČČàł àČȘàȰàČżàČ”àČ°àłàČ€àČšàł†àČŻ àȅàČ”àȧàČżàČŻàČČàłàČČàČż àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àČšàČ”àł€àȕàȰàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČżàČŠàł†.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àČŠàłƒàČąàł€àȕàȰàČżàČžàČČàł, àČšàČżàČźàłàČź àČžàȂàČȘàČ°àłàȕàČŠ àČžàČŸàȧàČšàČŠàłŠàȂàČŠàČżàČ—àł† àȕàČČàČ°àł àȕàČŸàČ°àłàČĄàłâ€Œ àČčàłŠàȂàČŠàČżàČžàČż. àȇàČ”àłàȗàČłàł àČčàłŠàȂàČŠàČżàČ•àł†àČŻàČŸàȗàČŠàČżàČŠàłàČŠàČ°àł†, àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àȗàČł àȇàČšàłàČšàłŠàȂàČŠàł àČœàłŠàČ€àł†àČŻàČšàłàČšàł àČȘàłàȰàČŻàČ€àłàČšàČżàČžàČż. àČ•àł‡àČ”àČČ àȒàȂàČŠàł àČœàłŠàČ€àł† àČčàłŠàȂàČŠàČżàČ•àł†àČŻàČŸàȗàČŹàł‡àČ•àł.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àČžàČčàČŸàČŻ àȅàȗàČ€àłàČŻàČ”àČżàČŠàł†àČŻàł‡?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àȅàČ°àłàČ„àČ”àČŸàČŻàČżàČ€àł", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àČšàł€àČ”àł àȈ àČ”àłàČŻàČ•àłàČ€àČżàČŻàłŠàȂàČŠàČżàČ—àł† àČźàł†àČžàł‡àČœàłâ€ŒàȗàČłàČšàłàČšàł àČ”àČżàČšàČżàČźàČŻ àČźàČŸàČĄàČżàČŠ àČŹàČłàČżàȕ àȅàČ”àČ°àłŠàȂàČŠàČżàȗ àȒàȂàČŠàł àČžàłàȰàČ•àłàČ·àČŸ àČžàȂàČ–àłàČŻàł†àČŻàČšàłàČšàł àȰàȚàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČŠàł†.", @@ -1267,10 +1359,6 @@ "messageformat": "àȇàČ€àłàČ€àł€àȚàČżàČš àČźàČŸàČ§àłàČŻàČźàČ”àČšàłàČšàł àČšàł‹àČĄàČż", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} àȅàČ”àČ°àłŠàȂàČŠàČżàȗàČżàČš àČšàČżàČźàłàČź àȎàȂàČĄàł àČŸàł àȎàȂàČĄàł àȎàČšàłâ€ŒàČ•àłàȰàČżàČȘàłàȶàČšàł àČ­àČŠàłàȰàČ€àł†àČŻàČšàłàČšàł àČŠàłƒàČąàł€àȕàȰàČżàČžàČČàł, àȅàČ”àȰ àČžàČŸàȧàČšàȗàČłàłŠàȂàČŠàČżàČ—àł† àČźàł‡àČČàČżàČš àČžàȂàČ–àłàČŻàł†àȗàČłàČšàłàČšàł àČčàł‹àČČàČżàČ•àł† àČźàČŸàČĄàČż. àȅàČ”àČ°àł àČ•àł‚àČĄàČŸ àČźàł‡àČČàČżàČš àČ•àłàČŻàł‚àȆàČ°àł àČ•àł‹àČĄàł àȅàČšàłàČšàł àČžàłàČ•àłàČŻàČŸàČšàł àČźàČŸàČĄàČŹàČčàłàČŠàł.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àČšàł€àČ”àł àȇàČšàłàČšàł‚ àȈ àČžàȂàČȘàČ°àłàȕàČŠàłŠàȂàČŠàČżàČ—àł† àČŻàČŸàČ”àłàČŠàł‡ àČžàȂàČŠàł‡àȶàȗàČłàČšàłàČšàł àČ”àČżàČšàČżàČźàČŻ àČźàČŸàČĄàČżàČČàłàČČ. àȅàČ”àČ°àłŠàȂàČŠàČżàČ—àł† àČšàČżàČźàłàČź àČžàłàȰàČ•àłàČ·àČ€àČŸ àČžàȂàČ–àłàČŻàł† àČźàłŠàČŠàČČ àČžàȂàČŠàł‡àȶàČŠ àČšàȂàČ€àȰ àČČàČ­àłàČŻàČ”àČżàČ°àłàČ€àłàČ€àČŠàł†." }, @@ -1334,17 +1422,17 @@ "messageformat": "àČźàČŸàČčàČżàČ€àČż", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àȅàČłàČżàČžàČż", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àČźàł†àČžàł‡àČœàłâ€ŒàȗàČłàČšàłàČšàł àȅàČłàČżàČžàČż", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àȚàČŸàČŸàł àȅàČłàČżàČžàČŹàł‡àČ•àł†?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àČźàł†àČžàł‡àČœàłâ€â€ŒàȗàČłàČšàłàČšàł àȅàČłàČżàČžàČŹàł‡àČ•àł†?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àȈ àȚàČŸàČŸàł àȅàČšàłàČšàł àȈ àČžàČŸàȧàČšàČŠàČżàȂàČŠ àȅàČłàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČŠàł†.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àȈ àČžàČŸàȧàČšàČŠàČżàȂàČŠ àȈ àȚàČŸàČŸàłâ€ŒàČšàČČàłàČČàČżàČ°àłàČ” àČźàł†àČžàł‡àČœàłâ€ŒàȗàČłàČšàłàČšàł àȅàČłàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČŠàł†. àČšàł€àČ”àł àČźàł†àČžàł‡àČœàłâ€ŒàȗàČłàČšàłàČšàł àȅàČłàČżàČžàČżàČŠ àČšàȂàČ€àȰàČ”àł‚ àȈ àȚàČŸàČŸàłâ€Œ àȅàČšàłàČšàł àČšàł€àČ”àł àČčàłàČĄàłàȕàČŹàČčàłàČŠàł.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àČ—àłàČ°àł‚àČȘàł àȅàČšàłàČšàł àČ€àłŠàČ°àł†àČŻàČżàȰàČż", @@ -1438,6 +1526,14 @@ "messageformat": "àȎàȰàČĄàł‚ àȚàČŸàČŸàłâ€ŒàȗàČł àČšàČżàČźàłàČź àČźàł†àČžàł‡àČœàł àȇàČ€àČżàČčàČŸàČžàČ”àČšàłàČšàł àȇàČČàłàČČàČż àČ”àČżàČČàł€àČšàČ—àłŠàČłàČżàČžàČČàČŸàȗàČżàČŠàł†.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} àČŻàł {conversationTitle} àȅàČ”àȰàČŠàłàČŠàČŸàȗàČżàČŠàł†. àČšàł€àČ”àČżàČŹàłàČŹàČ°àł‚ {sharedGroup} àČš àČžàČŠàČžàłàČŻàȰàČŸàȗàČżàČŠàłàČŠàł€àȰàČż.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} àČŻàł {conversationTitle} àȅàČ”àȰàČŠàłàČŠàČŸàȗàČżàČŠàł†", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àČ•àł‹àČŸàł àČźàČŸàČĄàČżàČŠ àČźàł†àČžàł‡àČœàłâ€ŒàČšàČżàȂàČŠ àČ„àȂàČŹàłâ€ŒàČšàł‡àČČàł àȇàČźàł‡àČœàł", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àČźàČ€àłàČ€àł†àł‚àČźàłàČźàł† àȕàČ°àł† àČźàČŸàČĄàČż", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àȕàČ°àł† àȆàȰàȂàČ­àČżàČžàČż", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àȕàČ°àł†àČ—àł† àČžàł‡àȰàČż", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àȕàČ°àł†àČŻ àȗàČŸàČ€àłàȰàČŠàČżàȂàČŠàČŸàȗàČż àČźàłˆàČ•àłàČ°àł‹àČ«àł‹àČšàł àČźàłàČŻàł‚àČŸàł àȆàȗàČżàČŠàł†", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àȕàČ°àł† àȅàȧàČżàČžàł‚àȚàČšàł†àȗàČłàł", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àȕàČ°àł† àČ­àČ°àłàČ€àČżàČŻàČŸàȗàČżàČŠàł†", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àČ•àłàČŻàČŸàČźàȰàČŸ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àČžàł‡àȰàČżàČ•àłŠàČłàłàČłàČż", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àȆàȰàȂàČ­àČżàČžàČż", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àȕàČ°àł† àČ­àČ°àłàČ€àČżàČŻàČŸàȗàČżàČŠàł†", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àČ•àłàČŻàČŸàČźàȰàČŸ àČšàČżàČ·àłàČ•àłàȰàČżàČŻàČ—àłŠàČłàČżàČžàČČàČŸàȗàČżàČŠàł†", @@ -1621,10 +1725,6 @@ "messageformat": "àČ•àłàČŻàČŸàČźàȰàČŸ àȆàČšàł àČźàČŸàČĄàČż", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àČźàłàČŻàł‚àČŸàł àČźàČŸàČĄàČż", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àČźàłˆàČ•àłàČ°àł‹àČ«àł‹àČšàłâ€Œ àČšàČżàČ·àłàČ•àłàȰàČżàČŻàČ—àłŠàČłàČżàČžàČČàČŸàȗàČżàČŠàł†", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àČźàłˆàČ•àł àȅàČšàłâ€ŒàČźàłàČŻàł‚àČŸàł àČźàČŸàČĄàČż", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àČčàȂàȚàČżàČ•àł†àł‚àČłàłàČłàČż", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àČȘàłàČ°àł€àČžàł†àČŸàł àČźàČŸàČĄàłàČ”àłàČŠàČšàłàČšàł àČšàČżàČ·àłàČ•àłàȰàČżàČŻàČ—àłŠàČłàČżàČžàČČàČŸàȗàČżàČŠàł†", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àČȘàłàČ°àł†àČžàł†àȂàČŸàł àČźàČŸàČĄàłàČ”àłàČŠàČšàłàČšàł àČšàČżàČČàłàČČàČżàČžàČż", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àȰàČżàȂàČ—àł", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àČ­àČŸàȗàČżàȗàČł àČ•àł‚àȟ àČźàČŸàČĄàČČàł àČ—àłàČ°àł‚àČȘàł àČ€àł€àȰàČŸ àČŠàłŠàČĄàłàČĄàČŠàČŸàȗàČżàČŠàł†.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àȰàČżàȂàȗàČżàȂàČ—àł àȅàČšàłàČšàł àČžàČ•àłàȰàČżàČŻàČ—àłŠàČłàČżàČžàČż", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àȰàČżàȂàȗàČżàȂàČ—àł àȆàČ«àł àČźàČŸàČĄàČż", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àȰàČżàȂàȗàČżàȂàČ—àł àȆàČšàł àČźàČŸàČĄàČż", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àȇàČšàłàČšàČ·àłàČŸàł àȆàČŻàłàČ•àł†àȗàČłàł", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àČšàČżàł•àČ”àł", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àČšàČżàČźàłàČź àČ•àłàČŻàČŸàČźàȰàČŸ àȆàČ«àł àȆàȗàČżàČŠàł†", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àČžàłàȰàČ•àłàČ·àČ€àČŸ àČžàȂàČ–àłàČŻàł† àČ”àł€àČ•àłàČ·àČżàČžàČż", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àČźàł†àČžàł‡àČœàł", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àČžàłàȰàČ•àłàČ·àČ€àČŸ àČžàȂàČ–àłàČŻàł† àČ”àł€àČ•àłàČ·àČżàČžàČż", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "àČ«àł‹àČšàł àČšàȂàČŹàČ°àł àČȘàČĄàł†àČŻàČČàł àČ”àČżàČ«àČČàČ”àČŸàȗàČżàČŠàł†. àČšàČżàČźàłàČź àČžàȂàČȘàČ°àłàȕ àČȘàȰàČżàČ¶àł€àČČàČżàČžàČż àČčàČŸàČ—àł‚ àČźàČ€àłàČ€àłŠàČźàłàČźàł† àČȘàłàȰàČŻàČ€àłàČšàČżàČžàČż.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àČšàł€àČ”àł àȈ àČźàł†àČžàł‡àČœàł àȕàČłàłàČčàČżàČžàČżàČŠ 3 àȗàȂàČŸàł†àȗàČł àȒàČłàČ—àł† àČźàČŸàČ€àłàȰ àȎàČĄàČżàČŸàłâ€ŒàȗàČłàČšàłàČšàł àČšàł€àČ”àł àȅàČšàłàČ”àČŻàČżàČžàČŹàČčàłàČŠàł.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àČšàł€àČ”àł àȈ àČźàł†àČžàł‡àČœàł àȕàČłàłàČčàČżàČžàČżàČŠ 24 àȗàȂàČŸàł†àȗàČł àȒàČłàČ—àł† àČźàČŸàČ€àłàȰ àȎàČĄàČżàČŸàłâ€ŒàȗàČłàł àȅàČšàłàČ”àČŻàČżàČžàČŹàČčàłàČŠàł.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àȈ àČžàȂàČŠàł‡àȶàČ”àČšàłàČšàł àȅàČłàČżàČžàČČàČŸàȗàČżàČŠàł†.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àČȘàłàȰàČŠàČ°àłàȶàČżàČžàČČàł àČČàȗàČ€àłàČ€àł àČ€àł€àȰàČŸ àČŠàłŠàČĄàłàČĄàČŠàČŸàȗàČżàČŠàł†.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àČȘàłàȰàČŠàČ°àłàȶàČżàČžàČČàł àČ•àł†àČČàČ”àł àČČàȗàČ€àłàČ€àłàȗàČłàł àČ€àł€àȰàČŸ àČŠàłŠàČĄàłàČĄàČŠàČŸàȗàČżàČ”àł†.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àČŠàł‡àČŁàČżàČ—àł† àČ”àČżàČ”àȰàȗàČłàČšàłàČšàł àČȘàČĄàł†àČŻàČČàł àČžàČŸàČ§àłàČŻàČ”àČŸàČ—àłàČ€àłàČ€àČżàČČàłàČČ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal àČŹàł€àȟàČŸ àČźàČŸàČ€àłàȰ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àČźàł†àČžàł‡àČœàłâ€ŒàȗàČłàČšàłàČšàł àȎàČĄàČżàČŸàł àČźàČŸàČĄàłàČ”àČżàČ•àł†àČŻàł Signal àČŹàł€àȟàČŸ àČŹàČłàČ•àł†àČŠàČŸàȰàȰàČżàČ—àł† àČźàČŸàČ€àłàȰ àČČàČ­àłàČŻàČ”àČżàČŠàł†. àČźàł†àČžàł‡àČœàł àȅàČšàłàČšàł àČšàł€àČ”àł àȎàČĄàČżàČŸàł àČźàČŸàČĄàČżàČŠàČ°àł†, àȅàČŠàł Signal àČŹàł€àȟàČŸàČŠ àȇàČ€àłàČ€àł€àȚàČżàČš àȆàČ”àłƒàČ€àłàČ€àČżàČŻàČČàłàČČàČżàČ°àłàČ”àČ”àȰàČżàČ—àł† àČźàČŸàČ€àłàȰ àȕàČŸàČŁàłàČ€àłàČ€àČŠàł†.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àČźàł†àČžàł‡àČœàł àȎàČĄàČżàČŸàł àČźàČŸàČĄàČż", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àČšàł€àČ”àł àČźàł†àČžàł‡àČœàł àȅàČšàłàČšàł àȎàČĄàČżàČŸàł àČźàČŸàČĄàČżàČŠàČ°àł†, àȅàČŠàł Signal àČš àȇàČ€àłàČ€àł€àȚàČżàČš àȆàČ”àłƒàČ€àłàČ€àČżàȗàČłàČČàłàČČàČż àȇàČ°àłàČ”àČ”àȰàČżàČ—àł† àČźàČŸàČ€àłàȰ àȕàČŸàČŁàłàČ€àłàČ€àČŠàł†. àČšàł€àČ”àł àČźàł†àČžàł‡àČœàł àȅàČšàłàČšàł àȎàČĄàČżàČŸàł àČźàČŸàČĄàČżàČŠàČ°àł† àȅàČ”àȰàČżàČ—àł† àČšàł‹àČĄàČČàł àČžàČŸàČ§àłàČŻàČ”àČŸàČ—àłàČ€àłàČ€àČŠàł†.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àȒàČłàČŹàČ°àłàČ” àČ”àł€àČĄàČżàČŻàłŠ àȕàČ°àł†â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àČčàłŠàȰàČčàł‹àČ—àłàČ” àČ”àČŸàČŻàłàČžàł àȕàČŸàČČàł", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àČčàłŠàȰàČčàł‹àČ—àłàČ” àČ”àł€àČĄàČżàČŻàłŠ àȕàČŸàČČàł", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àȅàČ”àČ°àł àČšàČżàČźàČ—àł† àȕàČ°àł† àČźàČŸàČĄàłàČ€àłàČ€àČżàČŠàłàČŠàČŸàČ°àł†àł†", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àČźàČ°àłàČžàȂàČȘàČ°àłàȕàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČżàČŠàł†â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} person} other {{count,number} àȜàČšàČ°àł}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àȆàČĄàČżàČŻàłŠ àȕàČ°àł†", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àČźàłàČ•àłàČ€àČŸàČŻ", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àČ€àłŠàČ°àł†àČŻàČżàȰàČż", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àČźàłˆàČ•àł àȆàČ«àł àȆàȗàČżàČŠàł†", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àČźàłˆàČ•àł àȆàČšàł àȆàȗàČżàČŠàł†", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àȰàČżàȂàȗàČżàȂàČ—àł àȆàČšàł àȆàȗàČżàČŠàł†", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àȰàČżàȂàȗàČżàȂàČ—àł àȆàČ«àł", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àČžàł†àČŸàłàȟàČżàȂàČ—àłâ€ŒàȗàČłàł", @@ -3468,13 +3668,25 @@ "messageformat": "àČ«àłàČČàłâ€ŒàČžàłàČ•àłàČ°àł€àČšàł àȕàČŸàČČàł", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àČ—àłàȰàČżàČĄàł àČ”àłàČŻàł‚àČ—àł† àČŹàČŠàČČàČżàČžàČż", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àČ”àł€àČ•àłàČ·àČŁàł†àČŻàČšàłàČšàł àČŹàČŠàČČàČŸàČŻàČżàČžàČż", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àČžàłàČȘàł€àȕàČ°àł àČ”àłàČŻàł‚àČ—àł† àČŹàČŠàČČàČżàČžàČż", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àČ—àłàȰàČżàČĄàł àČ”àł€àČ•àłàČ·àČŁàł†", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àČžàłˆàČĄàłâ€ŒàČŹàČŸàČ°àł àČ”àł€àČ•àłàČ·àČŁàł†", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àČžàłàČȘàł€àȕàČ°àł àČ”àł€àČ•àłàČ·àČŁàł†", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àČ”àł€àČ•àłàČ·àČŁàł† àČšàČ”àł€àȕàȰàČŁàČ—àłŠàȂàČĄàČżàČŠàł†", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àȕàČ°àł† àČŹàČżàČĄàČż", @@ -3576,6 +3788,14 @@ "messageformat": "àČžàȰàČż", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àČźàł†àČžàł‡àČœàł àȅàČšàłàČšàł àȎàČĄàČżàČŸàł àČźàČŸàČĄàČČàł àČžàČŸàČ§àłàČŻàČ”àČżàČČàłàČČ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àȈ àČźàł†àČžàł‡àČœàłâ€ŒàČ—àł† {max,number} àȎàČĄàČżàČŸàłâ€ŒàȗàČłàČšàłàČšàł àČźàČŸàČ€àłàȰ àȅàČšàłàČ”àČŻàČżàČžàČŹàČčàłàČŠàČŸàȗàČżàČŠàł†.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àČ•àłàČ·àČźàČżàČžàČż, àȆ sgnl:// àČČàČżàȂàČ•àłâ€Œ àȅàČ°àłàČ„àČ”àČŸàȗàČżàČČàłàČČ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àČšàČżàČźàłàČź àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàłâ€ŒàČšàČČàłàČČàČż àȏàČšàł‹ àČ€àČȘàłàČȘàČŸàȗàČżàČŠàł†, àȅàČŠàČšàłàČšàł àȇàČšàłàČšàł àČźàłàȂàČŠàł† àČšàČżàČźàłàČź àȖàČŸàČ€àł†àČ—àł† àČšàČżàČŻàł‹àȜàČżàČžàČČàČŸàČ—àłàČ”àłàČŠàČżàČČàłàČČ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àȅàČłàČżàČžàČż", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àČŹàČłàČ•àł†àČŠàČŸàȰ àČčàł†àČžàȰàČšàłàČšàł àȰàȚàČżàČžàČż", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR àČ•àł‹àČĄàł àȅàČ„àČ”àČŸ àČČàČżàȂàČ•àł", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àȅàČšàłàČšàł àČźàČ°àłàČčàłŠàȂàČŠàČżàČžàČŹàł‡àȕàČżàČŠàł†", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àČČàČżàȂàČ•àł àȅàČšàłàČšàł àČźàČ°àłàČčàłŠàȂàČŠàČżàČžàČŹàł‡àȕàČżàČŠàł†", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àČšàČżàČźàłàČź àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àČčàȂàȚàČżàČ•àłŠàČłàłàČłàČż", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àȅàČłàČżàČžàČż", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àȇàČŠàł àČšàČżàČźàłàČź àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àȅàČšàłàČšàł àČ€àł†àČ—àł†àČŠàłàČčàČŸàȕàČČàČżàČŠàł†, àȇàČŠàČšàłàČšàł àČŹàł‡àČ°àł† àČŹàČłàČ•àł†àČŠàČŸàȰàČ°àł àČ•àłàČČàłˆàČźàł àČźàČŸàČĄàČČàł àȅàČ”àȕàČŸàȶ àČšàł€àČĄàČČàČŸàČ—àłàČ€àłàČ€àČŠàł†. àČšàł€àČ”àł àȖàȚàČżàČ€àČ”àČŸàȗàČżàČŠàłàČŠàł€àȰàČŸ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àȇàČŠàł àČšàČżàČźàłàČź àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àȅàČšàłàČšàł àČ€àł†àČ—àł†àČŠàłàČčàČŸàČ•àłàČ€àłàČ€àČŠàł† àČźàČ€àłàČ€àł àČšàČżàČźàłàČź QR àČ•àł‹àČĄàł àČźàČ€àłàČ€àł àČČàČżàȂàČ•àł àȅàČšàłàČšàł àČšàČżàČ·àłàČ•àłàȰàČżàČŻàČ—àłŠàČłàČżàČžàłàČ€àłàČ€àČŠàł†. àȇàČ€àȰàȰàČżàČ—àł† àČ•àłàČČàłˆàČźàł àČźàČŸàČĄàČČàł “{username}” àČČàČ­àłàČŻàČ”àČŸàȗàČČàČżàČŠàł†. àČšàČżàČźàČ—àł† àȖàČŸàČ€àłàȰàČżàČŻàČżàČŠàł†àČŻàł‡?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àČžàłàČŸàł‹àČ°àł€àČžàł àȅàČšàłàČšàł àČčàȂàȚàČżàČ•àłŠàČłàłàČłàČČàł àȅàČ„àČ”àČŸ àČ”àł€àČ•àłàČ·àČżàČžàČČàł àČšàČżàČźàČ—àł† àȇàČšàłàČšàł àČžàČŸàČ§àłàČŻàČ”àČżàČČàłàČČ. àČšàł€àČ”àł àȇàČ€àłàČ€àł€àČšàł†àČ—àł† àČčàȂàȚàČżàČ•àłŠàȂàČĄ àČžàłàČŸàł‹àȰàČż àȅàČȘàłâ€ŒàČĄàł‡àČŸàłâ€ŒàȗàČłàČšàłàČšàł àČ•àł‚àČĄàČŸ àȅàČłàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČŠàł†.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àČ­àČŸàČ·àł†", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àČ­àČŸàČ·àł†", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àČžàČżàČžàłàȟàČźàł àČ­àČŸàČ·àł†", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àČ­àČŸàČ·àł†àȗàČłàČšàłàČšàł àČčàłàČĄàłàȕàČż", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "{searchTerm} àČ—àł† àČ«àČČàČżàČ€àČŸàȂàȶàȗàČłàł àČČàČ­àłàČŻàČ”àČżàČČàłàČČ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àČčàłŠàȂàČŠàČżàČžàČż", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àȅàČšàłàČ”àČŻàČżàČžàČČàł Signal àȅàČšàłàČšàł àČźàČ°àłàČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČż", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àČ­àČŸàČ·àł†àČŻàČšàłàČšàł àČŹàČŠàČČàČŸàČŻàČżàČžàČČàł, àČ†àłàČŻàČȘàł àȅàČšàłàČšàł àČźàČ°àłàČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČŹàł‡àȕàČżàČŠàł†.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àČźàČ°àłàČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČż", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "àČČàČ­àłàČŻàČ”àČżàČ°àłàČ” àȆàČ”àłƒàČ€àłàČ€àČż {version} àČ•àłàČ•àł† àȅàČȘàłâ€ŒàČĄàł‡àČŸàł àČźàČŸàČĄàČż", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àČšàČżàČźàłàČź àČžàł†àČŸàłàȟàČżàȂàČ—àłâ€ŒàȗàČłàČšàłàČšàł àȉàČłàČżàČžàłàČ”àČŸàȗ àČŠàł‹àČ· àČžàȂàČ­àČ”àČżàČžàČżàČŠàł†. àČŠàČŻàČ”àČżàČŸàłàČŸàł àČźàČ€àłàČ€àłŠàČźàłàČźàł† àČȘàłàȰàČŻàČ€àłàČšàČżàČžàČż.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àČźàł†àČžàł‡àČœàł", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àȇàČšàłàČšàČ·àłàČŸàł àČ¶àłˆàČČàČżàȗàČłàł", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àČźàČ°àłàČčàł†àł‚àȂàČŠàČżàČžàČż", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àČźàłàȗàČżàČŠàČżàČŠàł†", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àČČàČżàȂàČ•àł àČŹàČŁàłàČŁ, {total,number} àČš {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àČšàČżàČźàłàČź QR àČ•àł‹àČĄàł àȅàČšàłàČšàł àČšàł€àČ”àł àČ°àł€àČžàł†àČŸàł àČźàČŸàČĄàČżàČŠàČ°àł†, àČšàČżàČźàłàČź àȅàČžàłàČ€àČżàČ€àłàČ”àČŠàČČàłàČČàČżàČ°àłàČ” QR àČ•àł‹àČĄàł àČźàČ€àłàČ€àł àČČàČżàȂàČ•àł àȕàČŸàČ°àłàČŻàČšàČżàČ°àłàČ”àČčàČżàČžàłàČ”àłàČŠàČżàČČàłàČČ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àČČàČżàȂàČ•àł àȅàČšàłàČšàł àČźàČ°àłàČčàłŠàȂàČŠàČżàČžàČČàČŸàČ—àłàČ€àłàČ€àČżàČŠàł†...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR àČ•àł‹àČĄàł àČźàČ€àłàČ€àł àČČàČżàȂàČ•àł àȅàČšàłàČšàł àČčàłŠàȂàČŠàČżàČžàČČàČŸàȗàČżàČČàłàČČ. àČšàČżàČźàłàČź àČšàł†àČŸàłâ€ŒàČ”àČ°àłàČ•àł àČžàȂàČȘàČ°àłàȕàČ”àČšàłàČšàł àČȘàȰàČżàČ¶àł€àČČàČżàČžàČż àČčàČŸàČ—àł‚ àȇàČšàłàČšàłŠàČźàłàČźàł† àČȘàłàȰàČŻàČ€àłàČšàČżàČžàČż.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àČšàČżàČźàłàČź Signal àČŻàł‚àČžàČ°àłâ€ŒàČšàł‡àČźàł àȅàČšàłàČšàł àČžàł†àȟàČȘàł àČźàČŸàČĄàČż", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "àČȘàłàČšàȃ àȕàČłàłàČčàČżàČžàČż", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àȇàČšàłàČšàČ·àłàČŸàł àČ•àłàȰàČźàȗàČłàł", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àȕàČ°àł†àȗàČłàł", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àČčàłŠàČž àȕàČ°àł†", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àČčàłŠàČž àȕàČ°àł†", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àȇàČšàłàČšàČ·àłàČŸàł àČ•àłàȰàČźàȗàČłàł", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àȕàČ°àł† àȇàČ€àČżàČčàČŸàČž àČ€àł†àȰàČ”àłàČ—àłŠàČłàČżàČžàČż", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àȕàČ°àł† àȇàČ€àČżàČčàČŸàČž àČ€àł†àȰàČ”àłàČ—àłŠàČłàČżàČžàČŹàł‡àČ•àł†?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àȇàČŠàł àȎàČČàłàČČàČŸ àȕàČ°àł† àȇàČ€àČżàČčàČŸàČžàČ”àČšàłàČšàł àȶàČŸàČ¶àłàČ”àČ€àČ”àČŸàȗàČż àȅàČłàČżàČžàłàČ€àłàČ€àČŠàł†", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àČ€àł†àȰàČ”àłàČ—àłŠàČłàČżàČžàČż", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àȕàČ°àł† àȇàČ€àČżàČčàČŸàČžàČ”àČšàłàČšàł àČ€àł†àȰàČ”àłàČ—àłŠàČłàČżàČžàČČàČŸàȗàČżàČŠàł†", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àȕàČ°àł†àČŻàČšàłàČšàł àČ”àł€àČ•àłàČ·àČżàČžàČČàł àȅàČ„àČ”àČŸ àČȘàłàȰàČŸàȂàČ­àČżàČžàČČàł àČ•àłàČČàČżàČ•àł àČźàČŸàČĄàČż", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àČčàłàČĄàłàȕàČż", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àČ€àČȘàłàČȘàČż àČčàł‹àČŠàČ”àłàȗàČłàł àȎàȂàČŹàłàČŠàČŸàȗàČż àČ«àČżàČČàłàȟàČ°àł àČźàČŸàČĄàČż", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àȟàČŸàȗàČČàł", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àȇàČ€àłàČ€àł€àȚàČżàČš àČŻàČŸàČ”àłàČŠàł‡ àȕàČ°àł†àȗàČłàČżàČČàłàČČ. àČžàłàČšàł‡àČčàČżàČ€àȰàČżàČ—àł† àȕàČ°àł† àČźàČŸàČĄàłàČ” àČźàł‚àČČàȕ àČȘàłàȰàČŸàȰàȂàČ­àČżàČžàČż.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "{query} àČ—àł† àČ«àČČàČżàČ€àČŸàȂàȶàȗàČłàł àČČàČ­àłàČŻàČ”àČżàČČàłàČČ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àȒàČłàČŹàČ°àłàČ”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àČčàłŠàȰàČčàł‹àČ—àłàČ”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àČ€àČȘàłàČȘàČżàČčàł‹àČŠ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àČ—àłàČ°àł‚àČȘàł àȕàČŸàČČàł", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àȇàČ€àłàČ€àł€àȚàČżàČš àČŻàČŸàČ”àłàČŠàł‡ àČžàȂàČ­àČŸàČ·àČŁàł†àȗàČłàČżàČČàłàČČ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "{query} àČ—àł† àČ«àČČàČżàČ€àČŸàȂàȶàȗàČłàł àČČàČ­àłàČŻàČ”àČżàČČàłàČČ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àČčàłŠàȰàČčàł‹àČ—àłàČ” àČ”àČŸàČŻàłàČžàł àȕàČŸàČČàł} other {àȒàČłàČŹàČ°àłàČ” àČ”àČŸàČŻàłàČžàł àȕàČŸàČČàł}}} Video {{direction, select, Outgoing {àČčàłŠàȰàČčàł‹àČ—àłàČ” àČ”àł€àČĄàČżàČŻàłŠ àȕàČŸàČČàł} other {àȒàČłàČŹàČ°àłàČ” àČ”àł€àČĄàČżàČŻàłŠ àȕàČŸàČČàł}}} Group {{direction, select, Outgoing {àČčàłŠàȰàČčàł‹àČ—àłàČ” àČ—àłàČ°àł‚àČȘàł àȕàČ°àł†} other {àȒàČłàČŹàČ°àłàČ” àČ—àłàČ°àł‚àČȘàł àȕàČ°àł†}}} other {{direction, select, Outgoing {àČčàłŠàȰàČčàł‹àČ—àłàČ” àȕàČ°àł†} other {àȒàČłàČŹàČ°àłàČ” àȕàČ°àł†}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àČźàČżàČžàłàČĄàł àČ”àČŸàČŻàłàČžàł àȕàČŸàČČàł} Video {àČźàČżàČžàłàČĄàł àČ”àł€àČĄàČżàČŻàłŠ àȕàČŸàČČàł} Group {àČ€àČȘàłàČȘàČżàČŠ àČ—àłàČ°àł‚àČȘàł àȕàČ°àł†} other {àČ€àČȘàłàČȘàČżàČŠ àȕàČ°àł†}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àȉàČ€àłàČ€àȰàČżàČžàČŠ àČ”àČŸàČŻàłàČžàł àȕàČŸàČČàł} Video {àȉàČ€àłàČ€àȰàČżàČžàČŠ àČ”àł€àČĄàČżàČŻàłŠ àȕàČŸàČČàł} Group {àȉàČ€àłàČ€àȰàČżàČžàČŠ àČ—àłàČ°àł‚àČȘàł àȕàČ°àł†} other {àȉàČ€àłàČ€àȰàČżàČžàČŠ àȕàČ°àł†}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àČšàČżàȰàČŸàȕàȰàČżàČžàČżàČŠ àČ§àłàČ”àČšàČż àȕàČ°àł†} Video {àČšàČżàȰàČŸàȕàȰàČżàČžàČżàČŠ àČ”àł€àČĄàČżàČŻàłŠ àȕàČ°àł†} Group {àČšàČżàȰàČŸàȕàȰàČżàČžàČżàČŠ àČ—àłàČ°àł‚àČȘàł àȕàČ°àł†} other {àČšàČżàȰàČŸàȕàȰàČżàČžàČżàČŠ àȕàČ°àł†}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} àȇàČ€àČ°àł† àČ”àłàČŻàČ•àłàČ€àČż àČŸàłˆàČȘàł àČźàČŸàČĄàłàČ€àłàČ€àČżàČŠàłàČŠàČŸàČ°àł†.} other {{count,number} àȇàČ€àȰ àČźàȂàČŠàČż àČŸàłˆàČȘàł àČźàČŸàČĄàłàČ€àłàČ€àČżàČŠàłàČŠàČŸàČ°àł†.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àČčàłŠàČžàČ€àł‡àČšàČżàČŠàł†", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àČžàČŁàłàČŁ àČŸàłàČ”àł€àČ•àłâ€ŒàȗàČłàł, àČŹàČ—àł àČ«àČżàČ•àłàČžàłâ€ŒàȗàČłàł àČźàČ€àłàČ€àł àȕàČŸàČ°àłàČŻàČ•àłàČ·àČźàČ€àł† àČ”àČ°àłàȧàČšàł†àȗàČłàł. Signal àČŹàČłàČžàłàČ€àłàČ€àČżàČ°àłàČ”àłàČŠàČ•àłàȕàČŸàȗàČż àȧàČšàłàČŻàČ”àČŸàČŠàȗàČłàł!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àȈ àČšàČ”àł€àȕàȰàČŁàČ”àł àČ§àłàČ”àČšàČż àČźàČ€àłàČ€àł àČ”àł€àČĄàČżàČŻàłŠ àȕàČ°àł†àȗàČłàČżàČ—àł† àČ•àł†àČČàČ”àł àČžàłàȧàČŸàȰàČŁàł†àȗàČłàČšàłàČšàł àȒàČłàČ—àłŠàȂàČĄàČżàČŠàł† àČźàČ€àłàČ€àł àČ•àł†àČČàČ”àł àČžàČŁàłàČŁ àČĄàČŸàČ•àłàČŻàłàČźàł†àȂàČŸàł‡àȶàČšàł àČšàČ”àł€àȕàȰàČŁàȗàČłàČšàłàČšàł àȒàČłàČ—àłŠàȂàČĄàČżàČŠàł† (àȧàČšàłàČŻàČ”àČŸàČŠàȗàČłàł, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "àȈàȗ àČšàČżàČźàłàČź àČžàČżàČžàłàȟàČźàł àČžàł†àČŸàłàȟàČżàȂàČ—àłâ€ŒàȗàČłàČšàłàČšàł àČŹàČŠàČČàČŸàČŻàČżàČžàČŠàł†àČŻàł‡ Signal àČšàČČàłàČČàČż àČšàČżàČźàłàČź àȆàČŻàłàČ•àł†àČŻ àČ­àČŸàČ·àł†àČŻàČšàłàČšàł àČšàł€àČ”àł àČŹàČŠàČČàČŸàČŻàČżàČžàČŹàČčàłàČŠàł (Signal àČžàł†àČŸàłàȟàČżàȂàČ—àłâ€ŒàȗàČłàł > àČ°àł‚àČȘ > àČ­àČŸàČ·àł†)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àČŻàČŸàȰàČŸàČŠàČ°àł‚ àČčàłŠàČžàČŠàČŸàȗàČż àČ—àłàČ°àł‚àČȘàłâ€ŒàČ—àł† àČžàł‡àȰàČżàČŠàČŸàȗ àȕàČŸàČŁàČżàČžàČżàČ•àłŠàČłàłàČłàłàČ”àȂàČ€àČč àČ—àłàČ°àł‚àČȘàł àȅàČȘàłâ€ŒàČĄàł‡àČŸàłâ€ŒàȗàČł àȅàȧàČżàČžàł‚àȚàČšàł† àȐàȕàČŸàČšàłâ€ŒàȗàČłàČšàłàČšàł àČšàČŸàČ”àł àČźàČŸàČ°àłàČȘàČĄàČżàČžàČżàČŠàłàČŠàł‡àČ”àł†. àȈ àȐàȕàČŸàČšàłâ€ŒàȗàČłàł, àČ”àČżàČ¶àł‡àČ·àČ”àČŸàȗàČż àČšàł€àČ”àł àČĄàČŸàČ°àłàČ•àł àČ„àł€àČźàłâ€ŒàČš àČĄàČŸàČ°àłàČ•àłâ€ŒàČšàł†àČžàłâ€Œâ€àČšàłŠàČłàČ—àł† àȇàČŠàłàČŠàČ°àł† àČžàłàČȘàČ·àłàȟàČ€àł†àČŻàČšàłàČšàł àČžàłàȧàČŸàȰàČżàČžàČČàł àČšàł†àȰàČ”àČŸàČ—àłàČ€àłàČ€àČ”àł†. àČčàČżàȂàČŠàČżàČš àȐàȕàČŸàČšàłâ€ŒàȗàČłàł àČ•àł‡àČ”àČČ àČĄàČŸàČ°àłàČ•àł àȅàČšàłàČšàł àȅàČłàČ”àČĄàČżàČžàČżàČ•àłŠàȂàČĄàČżàČ”àł†. àČčàłŠàČž àȐàȕàČŸàČšàłâ€ŒàȗàČłàł àȅàČŠàȰàČČàłàČČàł‡ àČčàłàČŸàłàȟàČż, àȅàČŠàȰàČżàȂàČŠàČČàł‡ àČ°àł‚àČȘàłàČ—àłŠàȂàČĄàČżàČ”àł†." + "icu:WhatsNew__v6.39--1": { + "messageformat": "MacOS àČžàČŸàȧàČšàȗàČłàČČàłàČČàČż àȕàČ°àł† àČČàČŸàČŹàČżàČ—àł† àČžàł‡àČ°àłàČ”àČŸàȗ àČ•àł†àČČàČ”àłŠàČźàłàČźàł† àČžàȂàČ­àČ”àČżàČžàłàČ€àłàČ€àČżàČŠàłàČŠ àČ€àłàČžàł àČ”àČżàČłàȂàČŹàČ”àČšàłàČšàł àČšàČŸàČ”àł àČžàȰàČżàČȘàČĄàČżàČžàČżàČŠàłàČŠàł‡àČ”àł†, àȇàČŠàȰàČżàȂàČŠàČŸàȗàČż àČźàł€àȟàČżàȂàČ—àłâ€ŒàČ—àł† àČžàł‡àČ°àłàČ”àČŸàȗ àȉàȂàȟàČŸàČ—àłàČ€àłàČ€àČżàČŠàłàČŠ àȅàČ°àłàȧ àČžàł†àČ•àł†àȂàČĄàł àČ”àČżàČłàȂàČŹàČŠ àČžàČźàČžàłàČŻàł† àȇàČšàłàČšàČżàČ°àłàČ”àłàČŠàČżàČČàłàČČ." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àČŻàČŸàȰàČŸàČŠàČ°àł‚ àČ—àłàȂàČȘàł àȕàČ°àł†àČ—àł† àČžàł‡àȰàČżàČŠàČŸàȗ àȅàČ„àČ”àČŸ àČ€àłŠàČ°àł†àČŠàČŸàȗ àČšàČŸàČ”àł àČ”àł€àČĄàČżàČŻàłŠ àČŸàłˆàČČàłâ€ŒàȗàČłàČżàȗàČŸàȗàČż àČȘàȰàČżàČ”àČ°àłàČ€àČšàł†àČŻ àȅàČšàČżàČźàł‡àČ·àČšàł àȅàČšàłàČšàł àČžàȰàČżàČȘàČĄàČżàČžàČżàČŠàłàČŠàł‡àČ”àł†. àČžàłàČšàł‡àČčàČżàČ€àȰ àČźàłàȖ àČ”àł€àČ•àłàČ·àČŁàł†àČ—àł† àČžàłàČČàłˆàČĄàł àȆàȗàČżàČ°àłàČ”àłàČŠàČšàłàČšàł àČšàł€àČ”àł àČšàł‹àČĄàČżàČŠàČŸàȗ, àȅàČŠàł àČžàČŸàČźàČŸàȜàČżàȕ àȚàČłàłàČ”àČłàČżàČŻàČŸàȗàČżàČŠàł†." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àȈàȗ àČšàł€àČ”àł àȚàČŸàČŸàł àČžàł†àČŸàłàȟàČżàȂàČ—àłâ€ŒàȗàČłàČšàłàČšàł àČ€àłàČ”àȰàČżàČ€àČ”àČŸàȗàČż àČȘàłàȰàČ”àł‡àȶàČżàČžàČČàł àȅàČ„àČ”àČŸ àȆ àȚàČŸàČŸàłâ€ŒàČšàČżàȂàČŠ àČŻàČŸàČ”àłàČŠàł‡ àȕàČŸàČŁàČŠ àČžàłàČŸàł‹àČ°àł€àČžàł àȅàČšàłàČšàł àČ”àł€àČ•àłàČ·àČżàČžàČČàł àȚàČŸàČŸàł àČčàł†àČĄàČ°àłâ€ŒàČšàČČàłàČČàČż àČȘàłàČ°àłŠàČ«àłˆàČČàł àČ«àł‹àČŸàł‹ àȅàČ„àČ”àČŸ àČ—àłàȂàČȘàł àȅàČ”àČ€àČŸàČ°àł àȅàČšàłàČšàł àČ•àłàČČàČżàČ•àł àČźàČŸàČĄàČŹàČčàłàČŠàł. àȧàČšàłàČŻàČ”àČŸàČŠàȗàČłàł, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ko/messages.json b/_locales/ko/messages.json index b093706d65..dfbc3911e0 100644 --- a/_locales/ko/messages.json +++ b/_locales/ko/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "데읎터ëČ ìŽìŠ€ 였넘", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "데읎터ëČ ìŽìŠ€ 였넘가 발생했슔니닀. 였넘넌 ëł”ì‚Źí•˜ì—Ź Signal 지원 팀에 ëŹžì œ 핮êČ°ì„ 요ìȭ할 수 있슔니닀. Signal을 바로 ì‚Źìš©í•Žì•Œ 하는 êČœìš° 데읎터넌 ì‚­ì œí•˜êł  닀시 시작할 수 있슔니닀.\n\n{link}을(넌) ë°©ëŹží•˜ì—Ź 지원 팀에 ëŹžì˜í•˜ì„žìš”.", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ëȘšë“  데읎터 삭제 후 ìžŹì‹œìž‘", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "데읎터 삭제 후 닀시 시작", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ëȘšë“  데읎터넌 ì˜ê”Ź 삭제하시êČ ìŠ”ë‹ˆêčŒ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ëȘšë“  메시지 êž°ëĄêłŒ ëŻžë””ì–Žê°€ 읎 ꞰꞰ에서 ì˜ê”Ź 삭제됩니닀. 닀시 연êȰ한 후 읎 ꞰꞰ에서 Signal을 ì‚Źìš©í•  수 있슔니닀. 휮대폰 데읎터는 삭제하지 않슔니닀.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "데읎터ëČ ìŽìŠ€ ëČ„ì „ìŽ 읎 ëČ„ì „ì˜ SignalêłŒ 음ìč˜í•˜ì§€ 않슔니닀. 컎퓚터에서 씜신 ëČ„ì „ Signal을 엎었는지 확읞하섞요.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "파음 (&F)", @@ -300,6 +316,70 @@ "messageformat": "대화", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ì‚Źìš©ìž 읎늄에 ëŹžì œê°€ 생êČš 더는 읎 ì‚Źìš©ìž 읎늄읎 읎 êł„ì •ì— ì‚Źìš©ë˜ì§€ 않슔니닀. 닀시 ì„€ì •í•˜ë €êł  시도하거나 ìƒˆëĄœìšŽ ì‚Źìš©ìž 읎늄을 선택할 수 있슔니닀.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "지ꞈ 핮êȰ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "QR 윔드와 ì‚Źìš©ìž 읎늄 ë§íŹì— ëŹžì œê°€ ë°œìƒí•˜ì—Ź 더 읎상 ì‚Źìš©í•  수 없슔니닀. 닀넞 ì‚Źìš©ìžì™€ êł”ìœ í•˜ë €ë©Ž ìƒˆëĄœìšŽ ë§íŹë„Œ 만드섞요.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "지ꞈ 핮êȰ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "탭 표시", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "탭 숚ꞰꞰ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "였넘가 발생핚", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "읜지 않은 메시지 {count,number}개", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "읜지 ì•ŠìŒìœŒëĄœ 표시", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "대화", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "전화", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ìŠ€í† ëŠŹ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "섀정", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "시귞널 씜신 ëČ„ì „ìœŒëĄœ 업데읎튞", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "프로필", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ë’€ëĄœ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "읎 대화듀은 ëłŽêŽ€ ìČ˜ëŠŹë˜ì—ˆìœŒë©° 새 메시지넌 받을 때에만 받은 메시지에 표시됩니닀.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "귞냄 전화", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ëłŽë‚Žêž°", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "êł„ì† 전화", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "안전 ëČˆí˜žê°€ 업데읎튞됩니닀.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "더 ì•Œì•„ëłŽêž°", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "읎전 안전 ëȈ혞", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "닀음 안전 ëȈ혞", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "안전 ëȈ혞 ëČ„ì „, {index,number}/{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "êČ€ìŠìœŒëĄœ 표시", @@ -663,33 +747,41 @@ "messageformat": "읞슝 쎈Ʞ화하Ʞ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} ë‹˜êłŒì˜ ì—”ë“œíˆŹì—”ë“œ 암혞화넌 êČ€ìŠí•˜ë €ë©Ž 상Ʞ ëČˆí˜žë„Œ 상대방 ꞰꞰ의 ëČˆí˜žì™€ ëč„ꔐ하섞요. 상대방 êž°êž°ëĄœ 귀하의 윔드넌 슀ìș”í•  수도 있슔니닀.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "더 ì•Œì•„ëłŽêž°", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} ë‹˜êłŒì˜ ì—”ë“œíˆŹì—”ë“œ 암혞화넌 êČ€ìŠí•˜ë €ë©Ž 상Ʞ ì»ŹëŸŹ ìčŽë“œì™€ 상대방 ꞰꞰ넌 ëč„ê”í•˜ì—Ź 핮ë‹č ëČˆí˜žê°€ 음ìč˜í•˜ëŠ”ì§€ 확읞하섞요. 음ìč˜í•˜ì§€ 않윌멎 닀넞 안전 ëȈ혞 쌍을 시도핎 ëłŽì„žìš”. 한 쌍만 음ìč˜í•˜ë©Ž 됩니닀.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} ë‹˜êłŒì˜ ì—”ë“œíˆŹì—”ë“œ 암혞화넌 êČ€ìŠí•˜ë €ë©Ž 상Ʞ ëČˆí˜žë„Œ 상대방 ꞰꞰ의 ëČˆí˜žì™€ ëč„ꔐ하섞요. 상대방 êž°êž°ëĄœ 귀하의 윔드넌 슀ìș”í•  수도 있슔니닀.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "안전 ëȈ혞 변êČœ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "전환 Ʞ간에 안전 ëČˆí˜žê°€ 업데읎튞 되얎 ì•žìœŒëĄœ Signal에서 예정된 ê°œìžì •ëłŽ 볎혞 Ʞ늄읎 활성화됩니닀.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "안전 ëČˆí˜žë„Œ êČ€ìŠí•˜ë €ë©Ž ì»ŹëŸŹ ìčŽë“œê°€ 연띜ìȘ ꞰꞰ의 ì»ŹëŸŹ ìčŽë“œì™€ 음ìč˜í•˜ëŠ”ì§€ 확읞하섞요. 음ìč˜í•˜ì§€ 않윌멎 닀넞 안전 ëȈ혞 쌍을 시도핎 ëłŽì„žìš”. 한 쌍만 음ìč˜í•˜ë©Ž 됩니닀.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "도움읎 필요하신가요?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "확읞", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "메시지넌 ìŁŒêł ë°›ì€ 후 상대와의 메시지 ëłŽì•ˆì„ 위한 안전 ëČˆí˜žê°€ 생성됩니닀.", @@ -1267,10 +1359,6 @@ "messageformat": "씜귌 ëŻžë””ì–Ž ëłŽêž°", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} ë‹˜êłŒì˜ ì—”ë“œíˆŹì—”ë“œ 암혞화 ëłŽì•ˆì„ êČ€ìŠí•˜ë €ë©Ž 상Ʞ ëČˆí˜žë„Œ 상대방 ëČˆí˜žì™€ ëč„ꔐ하섞요. 상대방 êž°êž°ëĄœ 상Ʞ QR 윔드넌 슀ìș”í•  수도 있슔니닀.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "아직 읎 연띜ìČ˜ì™€ 메시지넌 ìŁŒêł ë°›ì€ 적읎 없슔니닀. 안전 ëȈ혾는 ìČ« ëČˆì§ž 메시지넌 ìŁŒê±°ë‚˜ 받은 읎후 읎용 가늄합니닀." }, @@ -1334,17 +1422,17 @@ "messageformat": "ì •ëłŽ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "삭제", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "메시지 삭제", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "대화넌 삭제하시êČ ìŠ”ë‹ˆêčŒ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "메시지넌 삭제하시êČ ìŠ”ë‹ˆêčŒ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "읎 ꞰꞰ에서 읎 대화넌 삭제합니닀.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "읎 대화의 메시지가 ꞰꞰ에서 삭제됩니닀. 메시지넌 삭제한 후에도 읎 대화넌 êł„ì† êČ€ìƒ‰í•  수 있슔니닀.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ê·žëŁč 나가Ʞ", @@ -1438,6 +1526,14 @@ "messageformat": "두 대화의 메시지 êž°ëĄìŽ ì—Źêž°ì— ëł‘í•©ë©ë‹ˆë‹€.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber}ëČˆì€ {conversationTitle} 님의 전화ëČˆí˜žìž…ë‹ˆë‹€. 두 ì‚ŹëžŒ ë‹€ {sharedGroup}의 ë©€ëČ„ìž…ë‹ˆë‹€.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber}ëČˆì€ {conversationTitle} 님의 전화ëČˆí˜žìž…ë‹ˆë‹€.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "읞용된 메시지의 ìŽëŻžì§€ ì„Źë„€ìŒ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "닀시 걞Ʞ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "전화 시작하Ʞ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "전화 ì°žì—Źí•˜êž°", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "톔화 규ëȘšëĄœ 읞핎 ë§ˆìŽíŹê°€ 음소거 ìČ˜ëŠŹë˜ì—ˆìŠ”ë‹ˆë‹€.", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "전화 알늌", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "톔화 찞가자 수 씜대", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ìčŽë©”띌", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ì°žê°€", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "시작", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "톔화 씜대 찞가자 수 도달", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ìčŽë©”띌 ëč„활성화", @@ -1621,10 +1725,6 @@ "messageformat": "ìčŽë©”띌 쌜Ʞ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "음소거", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "ë§ˆìŽíŹ ëč„활성화", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ë§ˆìŽíŹ 음소거 핎제", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "êł”ìœ ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "표시 ëč„활성화됚", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "표시 쀑닚", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "전화ëČš", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "당ìČŽ ì°žì—Źìžê°€ 너묮 많아 톔화넌 진행할 수 없슔니닀.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "전화ëČš ì‚Źìš©", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "톔화 끄Ʞ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "톔화 쌜Ʞ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "옔션 더 ëłŽêž°", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "나", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ìčŽë©”띌가 êșŒìĄŒìŠ”니닀.", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "안전 ëȈ혞 ëłŽêž°", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "메시지", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "안전 ëȈ혞 ëłŽêž°", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "전화ëČˆí˜žë„Œ 가젞였지 ëȘ»í–ˆìŠ”니닀. 연êČ°ì„ í™•ìží•˜êł  닀시 시도하섞요.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "메시지 수정은 ë°œì†Ą ì‹œê°„ìœŒëĄœë¶€í„° 3시간 ìŽë‚ŽëĄœ 제한됩니닀.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "메시지 수정은 ë°œì†Ą ì‹œê°„ìœŒëĄœë¶€í„° 24시간 읎낎에 핎알 합니닀.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ëłž 메섞지는 삭제되었슔니닀.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ìČšë¶€ 파음읎 너묮 컀서 표시할 수 없슔니닀.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "음부 ìČšë¶€ 파음읎 너묮 컀서 표시할 수 없슔니닀.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "êž°ë¶€ 섞부 ì •ëłŽë„Œ 가젞였지 ëȘ»í–ˆìŠ”니닀.", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal ëȠ타 전용", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "메시지 수정은 Signal ëȠ타 ì‚Źìš©ìžë§Œ ì‚Źìš©í•  수 있슔니닀. 메시지넌 수정하멎 Signal ëȠ타 씜신 ëČ„ì „ì„ ì‚Źìš©í•˜ëŠ” ì‚Źìš©ìžì—êȌ만 표시됩니닀.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "메시지 수정", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "메시지넌 수정하멎 Signal 씜신 ëČ„ì „ì„ ì‚Źìš©í•˜ëŠ” ì‚Źìš©ìžì—êȌ만 표시됩니닀. 핮ë‹č ì‚Źìš©ìžëŠ” 수정 메시지넌 ëłŒ 수 있슔니닀.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "영상 톔화 수신 쀑 ", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "발신 음성 톔화", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "발신 영상 톔화", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} 님읎 나에êȌ 전화넌 걞었슔니닀.", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "닀시 연êȰ 쀑 ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number}ëȘ…}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "음성 톔화", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ìą…ëŁŒ", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "나가Ʞ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "ë§ˆìŽíŹ êșŒì§", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "ë§ˆìŽíŹ 쌜짐", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "톔화 쌜짐", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "톔화 êșŒì§", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "섀정", @@ -3468,13 +3668,25 @@ "messageformat": "전ìȎ화멎 톔화", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ê·žëŠŹë“œ ë·°ëĄœ 전환", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ëłŽêž° 변êČœ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "슀플컀 ë·°ëĄœ 전환", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ê·žëŠŹë“œ ëłŽêž°", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ì‚ŹìŽë“œë°” ëłŽêž°", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "말하는 ì‚ŹëžŒ ëłŽêž°", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ëłŽêž° 업데읎튞 ì™„ëŁŒ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "전화 ìą…ëŁŒ", @@ -3576,6 +3788,14 @@ "messageformat": "확읞", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "메시지넌 수정할 수 없슔니닀", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "읎 메시지는 {max,number}ëȈ만 수정할 수 있슔니닀.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ìŁ„ì†Ąí•Žìš”. 읎 sgnl:// ë§íŹê°€ 잘ëȘ»ë˜ì—ˆì–Žìš”!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ì‚Źìš©ìž 읎늄", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ì‚Źìš©ìž 읎늄에 ëŹžì œê°€ 생êČš 더는 읎 ì‚Źìš©ìž 읎늄읎 읎 êł„ì •ì— ì‚Źìš©ë˜ì§€ 않슔니닀.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ì‚Źìš©ìž 읎늄 삭제", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ì‚Źìš©ìž 읎늄 생성", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR 윔드 또는 링큏", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ì‚Źìš©ìž 읎늄 쎈Ʞ화 필요", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ì‚Źìš©ìž 읎늄 링큏 쎈Ʞ화 필요", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "낮 ì‚Źìš©ìž 읎늄 êł”ìœ ", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ì‚Źìš©ìž 읎늄 삭제", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ì‚Źìš©ìž 읎늄을 삭제하멎 닀넞 ì‚Źìš©ìžê°€ ì‚Źìš©í•  수 있êȌ 됩니닀. êł„ì†í• êčŒìš”?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ì‚Źìš©ìž 읎늄읎 ì œê±°ë˜êł  QR 윔드와 ë§íŹë„Œ ì‚Źìš©í•  수 없êȌ 되며, ''{username}'을(넌) 닀넞 ì‚Źìš©ìžê°€ ì‚Źìš©í•  수 있êȌ 됩니닀. êł„ì†í• êčŒìš”?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "더 읎상 ìŠ€í† ëŠŹë„Œ êł”ìœ í•˜ê±°ë‚˜ ëłŒ 수 없슔니닀. 씜귌 êł”ìœ í•œ ìŠ€í† ëŠŹ 업데읎튞도 삭제합니닀.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ì–žì–Ž", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ì–žì–Ž", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "시슀템 ì–žì–Ž", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ì–žì–Ž êČ€ìƒ‰", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” êČ€ìƒ‰ êČ°êłŒ 없음", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "섀정", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "적용하렀멎 Signal 닀시 시작", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "얞얎넌 적용하렀멎 앱을 닀시 시작핎알 합니닀.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "닀시 시작", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} ëČ„ì „ìœŒëĄœ 업데읎튞할 수 있슔니닀.", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "섀정 저임 쀑 ëŹžì œê°€ 발생했슔니닀. 닀시 시도하섞요.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "메시지", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "더 많은 슀타음", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "쎈Ʞ화", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "확읞", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ì‚Źìš©ìž 읎늄 링큏 색, {index,number}/{total,number}개", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "QR 윔드넌 쎈Ʞ화하멎 êž°ìĄŽ QR 윔드와 ë§íŹê°€ 더 읎상 작동하지 않슔니닀.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ë§íŹë„Œ 쎈Ʞ화하는 쀑...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR 윔드와 ë§íŹë„Œ 섀정하지 않았슔니닀. ë„€íŠžì›ŒíŹ 연êČ°ì„ í™•ìží•˜êł  닀시 시도하섞요.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Signal ì‚Źìš©ìž 읎늄 섀정", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "닀시 ëłŽë‚Žêž°", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "더 많은 작업", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "전화", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "새 톔화", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "새 톔화", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "더 많은 작업", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "톔화 êž°ëĄ 지우Ʞ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "톔화 êž°ëĄì„ 지욞êčŒìš”?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ëȘšë“  톔화 êž°ëĄì„ ì˜ê”Ź 삭제합니닀.", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "제거", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "톔화 êž°ëĄì„ ì •ëŠŹí•š", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "íŽëŠ­í•˜ì—Ź 톔화 ëłŽêž° 또는 시작", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "êČ€ìƒ‰", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ë¶€ìžŹì€‘ìœŒëĄœ 필터링", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "토Ꞁ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "씜귌 톔화 없음 ìčœê”Źì—êȌ 전화넌 걞얎 시작하섞요.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” êČ€ìƒ‰ êČ°êłŒ 없음", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "수신", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "발신", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ë¶€ìžŹì€‘", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ê·žëŁč 톔화", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "씜귌 대화 없음.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” êČ€ìƒ‰ êČ°êłŒ 없음", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {발신 음성 톔화} other {수신 음성 톔화}}} Video {{direction, select, Outgoing {발신 영상 톔화} other {수신 영상 톔화}}} Group {{direction, select, Outgoing {발신 ê·žëŁč 톔화} other {수신 ê·žëŁč 톔화}}} other {{direction, select, Outgoing {발신 전화} other {수신 전화}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ë¶€ìžŹì€‘ 음성 톔화} Video {ë¶€ìžŹì€‘ 영상 톔화} Group {ë¶€ìžŹì€‘ ê·žëŁč 톔화} other {ë¶€ìžŹì€‘ 전화}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ëŻžì‘ë‹” 음성 톔화} Video {응닔하지 않은 영상 톔화} Group {ê·žëŁč 톔화넌 받지 않음} other {톔화넌 받지 않음}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {음성 톔화넌 거부핚} Video {영상 톔화넌 거부핚} Group {ê·žëŁč 톔화넌 거부핚} other {톔화넌 거부핚}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number}ëȘ…읎 입렄하는 쀑입니닀.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "업데읎튞 낎용", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ì‚Źì†Œí•œ 변êČœ ì‚Źí•­êłŒ ëČ„ê·ž 수정 및 성늄 개선. Signal을 읎용핎 ìŁŒì…”ì„œ ê°ì‚Źí•©ë‹ˆë‹€!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "읎 업데읎튞는 음성 및 영상 톔화에 대한 ëȘ‡ 가지 개선 ì‚Źí•­êłŒ 소소한 ëŹžì„œ 업데읎튞넌 íŹí•ší•©ë‹ˆë‹€(êł ë§ˆì›Œìš”, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "읎제 시슀템 섀정을 변êČœí•˜ì§€ ì•Šêł  Signal 선택 얞얎넌 변êČœí•  수 있슔니닀(Signal 섀정 > 디자읞 > ì–žì–Ž)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "음부 ê·žëŁč 알늌 아읎윘을 업데읎튞했슔니닀." + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOS에서 톔화 로ëč„에 찞가한 후 간í˜č 발생하던 짧은 지연을 핮êČ°í–ˆìŠ”ë‹ˆë‹€." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "닀넞 ì‚ŹëžŒìŽ ê·žëŁč 톔화에 듀얎였거나 나갈 때 표시되는 동영상 타음의 전환 애니메읎션을 수정했슔니닀." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "읎제 대화 헀더에서 프로필 ì‚Źì§„ìŽë‚˜ ê·žëŁč 아바타넌 íŽëŠ­í•˜ì—Ź ëč ë„ŽêȌ 대화 섀정을 읎용하거나 대화의 확읞하지 않은 ìŠ€í† ëŠŹë„Œ 확읞할 수 있슔니닀. êł ë§ˆì›Œìš”, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ky-KG/messages.json b/_locales/ky-KG/messages.json index 5a8a79d701..d7b882d982 100644 --- a/_locales/ky-KG/messages.json +++ b/_locales/ky-KG/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ĐœĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚Ń‚Đ°Ń€ Đ±Đ°Đ·Đ°ŃŃ‹ĐœŃ‹Đœ Đșатасы", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ĐœĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚Ń‚Đ°Ń€ Đ±Đ°Đ·Đ°ŃŃ‹ĐœĐŽĐ° Đșата ĐșДттО. ĐšĐ°Ń‚Đ°ĐœŃ‹ ĐșÓ©Ń‡ÒŻŃ€ÒŻĐż, ĐŒĐ°ŃĐ”Đ»Đ”ĐœĐž Ń‡Đ”Ń‡ÒŻÒŻ ÒŻŃ‡ÒŻĐœ Signal'ĐŽŃ‹Đœ ĐșарЎарларЎы тДĐčĐ»Đ”ĐłĐ”Đœ Đ±Ó©Đ»ÒŻĐŒÒŻĐœÓ© ĐșаĐčŃ€Ń‹Đ»Ń‹ÒŁŃ‹Đ·. ЭгДр Signal'Юы азыр ĐșĐŸĐ»ĐŽĐŸĐœĐłŃƒÒŁŃƒĐ· ĐșДлсД, Đ°ĐœĐŽĐ°ĐłŃ‹ ĐœĐ”Ń€ŃĐ”Đ»Đ”Ń€ĐŽĐž Ó©Ń‡ÒŻŃ€ÒŻĐż, ĐșаĐčра ĐžŃˆŃ‚Đ”Ń‚ĐžÒŁĐžĐ·.\n\nКарЎарларЎы тДĐčĐ»Đ”ĐłĐ”Đœ ĐșŃ‹Đ·ĐŒĐ°Ń‚Đșа Ó©Ń‚ÒŻÒŁÒŻĐ·: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Đ‘Đ°Đ°Ń€Ń‹Đœ Ó©Ń‡ÒŻŃ€ÒŻĐż, ĐșаĐčра ĐžŃˆŃ‚Đ”Ń‚ÒŻÒŻ", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ĐœĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚Ń‚Đ°Ń€ĐŽŃ‹ Ó©Ń‡ÒŻŃ€ÒŻĐż, ĐșаĐčра ĐžŃˆŃ‚Đ”Ń‚ÒŻÒŻ", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Đ‘Đ°Đ°Ń€Ń‹Đœ Đ±ĐžŃ€ĐŸŃ‚ĐŸĐ»ĐŸ Ó©Ń‡ÒŻŃ€Ó©ŃÒŻĐ·Đ±ÒŻ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»Ń‹ Đ¶Đ°ĐœĐ° ĐŒĐ”ĐŽĐžĐ° фаĐčлЎар Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻÒŁÒŻĐ·ĐŽÓ©Đœ Đ±ĐžŃ€ĐŸŃ‚ĐŸĐ»ĐŸ Ó©Ń‡ÒŻĐż Đșалат. Signal'га ĐșаĐčра баĐčĐ»Đ°ĐœŃ‹ŃˆĐșĐ°ĐœĐŽĐ°Đœ ĐșĐžĐčĐžĐœ, Đ°ĐœŃ‹ ушул Ń‚ÒŻĐ·ĐŒÓ©Đșтө ĐșĐŸĐ»ĐŽĐŸĐœĐŸ бДрДсОз. ĐąĐ”Đ»Đ”Ń„ĐŸĐœŃƒÒŁŃƒĐ·ĐŽĐ°ĐłŃ‹ ĐșĐ°Đ»ĐłĐ°Đœ ĐœĐ”Ń€ŃĐ”Đ»Đ”Ń€ өчпөĐčт.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "ĐœĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚Ń‚Đ°Ń€ Đ±Đ°Đ·Đ°ŃŃ‹ĐœŃ‹Đœ ĐČĐ”Ń€ŃĐžŃŃŃ‹ Signal'ĐŽŃ‹Đœ ĐČĐ”Ń€ŃĐžŃŃŃ‹ĐœĐ° туура ĐșДлбДĐčт. ĐšĐŸĐŒĐżŃŒŃŽŃ‚Đ”Ń€ĐžÒŁĐžĐ·ĐŽĐ” Signal'ĐŽŃ‹Đœ ŃÒŁ аĐșырĐșы ĐČĐ”Ń€ŃĐžŃŃŃ‹Đœ Đ°Ń‡Ń‹ÒŁŃ‹Đ·.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ЀаĐčĐ»", @@ -300,6 +316,70 @@ "messageformat": "ĐœĐ°Đ”ĐșтДр", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽĐ° ĐŒĐ°ŃĐ”Đ»Đ” жаралып, аĐșĐșĐ°ŃƒĐœŃ‚ŃƒÒŁŃƒĐ·ĐłĐ° баĐčĐ»Đ°ĐœĐ±Đ°Đč ĐșалЎы. Дагы бОр Đ¶ĐŸĐ»Ńƒ ĐșаĐčталап ĐșÓ©Ń€ÒŻÒŁÒŻĐ· жД Đ¶Đ°ÒŁŃ‹ŃŃ‹Đœ Ń‚ÒŻĐ·ÒŻÒŁÒŻĐ·.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ĐžÒŁĐŽĐŸĐŸ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "QR ĐșĐŸĐŽ ĐŒĐ”ĐœĐ”Đœ ĐșĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡ŃƒĐœŃƒĐœ ŃˆĐžĐ»Ń‚Đ”ĐŒĐ”ŃĐžĐœĐŽĐ” Đșата ĐșДтĐșĐ”ĐœĐŽĐžĐșŃ‚Đ”Đœ, алар жарабаĐč ĐșалЎы. БашĐșалар ĐŒĐ”ĐœĐ”Đœ Đ±Ó©Đ»ÒŻŃˆÓ© Ń‚ŃƒŃ€ĐłĐ°Đœ Đ¶Đ°ÒŁŃ‹ ŃˆĐžĐ»Ń‚Đ”ĐŒĐ” Ń‚ÒŻĐ·ÒŻÒŁÒŻĐ·.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ĐžÒŁĐŽĐŸĐŸ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ÓšŃ‚ĐŒÓ©ĐșŃ‚Ó©Ń€ĐŽÒŻ ĐșÓ©Ń€ŃÓ©Ń‚ÒŻÒŻ", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ÓšŃ‚ĐŒÓ©ĐșŃ‚Ó©Ń€ĐŽÒŻ Đ¶Đ°ŃˆŃ‹Ń€ŃƒŃƒ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ката ĐșДттО", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ĐŸĐșула ŃĐ»Đ”Đș", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ОĐșула ŃĐ»Đ”Đș ЎДп Đ±Đ”Đ»ĐłĐžĐ»Đ”ĐœĐŽĐž", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ĐœĐ°Đ”ĐșтДр", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐ»Đ°Ń€", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ОĐșŃƒŃĐ»Đ°Ń€", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐąŃƒŃƒŃ€Đ°Đ»ĐŸĐŸ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal'Юы Đ¶Đ°ÒŁŃ‹Ń€Ń‚ŃƒŃƒ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„ĐžĐ»ŃŒ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "АртĐșа", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Đ‘ŃƒĐ» ĐŒĐ°Đ”ĐșтДр архоĐČЎДлОп, Đ¶Đ°ÒŁŃ‹ Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ ĐșĐ”Đ»ĐłĐ”ĐœĐŽĐ” ĐłĐ°ĐœĐ° ĐšĐ”Đ»ĐłĐ”Đœ Đșаттар ĐșŃƒŃ‚ŃƒŃŃƒĐœĐŽĐ° ĐșÓ©Ń€ÒŻĐœÓ©Ń‚.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Баары бОр Ń‡Đ°Đ»Đ°ĐŒ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Баары бОр ĐșĐŸŃˆŃƒĐ»ŃƒŃƒ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐœŃƒ ŃƒĐ»Đ°ĐœŃ‚ŃƒŃƒ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽĐŽĐŸŃ€Ńƒ Đ¶Đ°ÒŁŃ‹Ń€ŃƒŃƒĐŽĐ°.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ĐšĐ”ĐœĐ”ĐœĐžŃ€ŃŃĐș ĐŒĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐœŃƒŃ€ŃƒĐœĐșу ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "КоĐčĐžĐœĐșĐž ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒĐœŃƒĐœ ĐČĐ”Ń€ŃĐžŃŃŃ‹, {total,number} ĐžŃ‡ĐžĐœĐ”Đœ {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ЫрасталЎы ЎДп бДлгОлөө", @@ -663,33 +747,41 @@ "messageformat": "Đ«Ń€Đ°ŃŃ‚ĐŸĐŸĐœŃƒ Ó©Ń‡ÒŻŃ€ÒŻÒŻ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} ĐŒĐ”ĐœĐ”Đœ Đ±Đ°ŃˆŃ‚Đ°Đœ аяĐș ŃˆĐžŃ„Ń€Đ»Ó©Ó©ĐœÒŻ Ń‹Ń€Đ°ŃŃ‚ĐŸĐŸ ÒŻŃ‡ÒŻĐœ Đ¶ĐŸĐłĐŸŃ€ŃƒĐŽĐ°ĐłŃ‹ ĐșĐŸĐŽĐŽĐŸŃ€ĐŽŃƒ Đ°ĐœŃ‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻĐœÓ© Ўал ĐșĐ”Đ»Ń‚ĐžŃ€ĐžÒŁĐžĐ·. ĐšĐ°Đ°Đ»Đ°ŃĐ°ÒŁŃ‹Đ·, Đ°ĐœŃ‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻ ĐŒĐ”ĐœĐ”Đœ ĐșĐŸĐŽŃƒÒŁŃƒĐ·ĐŽŃƒ сĐșĐ°ĐœĐŽĐ°ŃĐ°ÒŁŃ‹Đ· Đ±ĐŸĐ»ĐŸŃ‚.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ĐšĐ”ĐœĐ”ĐœĐžŃ€ŃŃĐș ĐŒĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} арĐșŃ‹Đ»ŃƒŃƒ Đ±Đ°ŃˆŃ‚Đ°Đœ аяĐș ŃˆĐžŃ„Ń€Đ»Ó©Ó©ĐœÒŻ Ń‹Ń€Đ°ŃŃ‚ĐŸĐŸ ÒŻŃ‡ÒŻĐœ Đ¶ĐŸĐłĐŸŃ€ŃƒĐŽĐ°ĐłŃ‹ Ń‚ÒŻŃ ĐșĐ°Ń€Ń‚Đ°ŃŃ‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻĐœÓ© Ўал ĐșДлтОрОп, ĐșĐŸĐŽĐŽĐŸŃ€ĐŽŃƒ ŃĐ°Đ»Ń‹ŃˆŃ‚Ń‹Ń€Ń‹ÒŁŃ‹Đ·. ЭгДр алар Ўал ĐșДлбДсД, ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽĐŽĐŸŃ€ŃƒĐœŃƒĐœ башĐșа Đ¶ŃƒĐ±ŃƒĐœ баĐčĐșап ĐșÓ©Ń€ÒŻÒŁÒŻĐ·. Бор ĐłĐ°ĐœĐ° Đ¶ŃƒĐżŃ‚Ńƒ Ўал ĐșĐ”Đ»Ń‚ĐžŃ€ÒŻÒŻ ĐșДрДĐș.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} ĐŒĐ”ĐœĐ”Đœ Đ±Đ°ŃˆŃ‚Đ°Đœ аяĐș ŃˆĐžŃ„Ń€Đ»Ó©Ó©ĐœÒŻ Ń‹Ń€Đ°ŃŃ‚ĐŸĐŸ ÒŻŃ‡ÒŻĐœ Đ¶ĐŸĐłĐŸŃ€ŃƒĐŽĐ°ĐłŃ‹ ĐșĐŸĐŽĐŽĐŸŃ€ĐŽŃƒ Đ°ĐœŃ‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻĐœÓ© Ўал ĐșĐ”Đ»Ń‚ĐžŃ€ĐžÒŁĐžĐ·. ĐšĐ°Đ°Đ»Đ°ŃĐ°ÒŁŃ‹Đ·, Đ°ĐœŃ‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻ ĐŒĐ”ĐœĐ”Đœ ĐșĐŸĐŽŃƒÒŁŃƒĐ·ĐŽŃƒ сĐșĐ°ĐœĐŽĐ°ŃĐ°ÒŁŃ‹Đ· Đ±ĐŸĐ»ĐŸŃ‚.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽĐŽĐŸŃ€ŃƒĐœŃƒĐœ Ó©Đ·ĐłÓ©Ń€ÒŻŃˆÒŻ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal'Ўа Đ±ĐŸĐ»ĐŸŃ‡ĐŸĐș ĐșŃƒĐżŃƒŃĐ»Ń‹Đș Ń„ŃƒĐœĐșŃ†ĐžŃĐ»Đ°Ń€Ń‹Đœ ĐžŃˆŃ‚Đ”Ń‚ÒŻÒŻ ÒŻŃ‡ÒŻĐœ ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽĐŽĐŸŃ€Ńƒ Ó©Ń‚ĐșÓ©Ó©Đ» ĐŒĐ”Đ·ĐłĐžĐ»ĐŽĐ” Đ¶Đ°ÒŁŃ‹Ń€Đ°Ń‚.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽĐŽĐŸŃ€ŃƒĐœ Ń‹Ń€Đ°ŃŃ‚ĐŸĐŸ ÒŻŃ‡ÒŻĐœ Ń‚ÒŻŃ ĐșĐ°Ń€Ń‚Đ°ŃŃ‹Đœ баĐčĐ»Đ°ĐœŃ‹ŃˆŃ‚Ń‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻĐœÓ© Ўал ĐșĐ”Đ»Ń‚ĐžŃ€ĐžÒŁĐžĐ·. ЭгДр алар Ўал ĐșДлбДсД, ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽĐŽĐŸŃ€ŃƒĐœŃƒĐœ башĐșа Đ¶ŃƒĐ±ŃƒĐœ баĐčĐșап ĐșÓ©Ń€ÒŻÒŁÒŻĐ·. Бор ĐłĐ°ĐœĐ° Đ¶ŃƒĐżŃ‚Ńƒ Ўал ĐșĐ”Đ»Ń‚ĐžŃ€ÒŻÒŻ ĐșДрДĐș.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Đ–Đ°Ń€ĐŽĐ°ĐŒ ĐșДрДĐșпО?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ĐąÒŻŃˆÒŻĐœĐŽÒŻĐŒ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Đ‘ŃƒĐ» Đ°ĐŽĐ°ĐŒĐŽŃ‹Đœ ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒ Đ°ĐœŃ‹ ĐŒĐ”ĐœĐ”Đœ Đ¶Đ°Đ·Ń‹ŃˆĐșĐ°ĐœĐŽĐ°Đœ ĐșĐžĐčĐžĐœ Ń‚ÒŻĐ·ÒŻĐ»Ó©Ń‚.", @@ -1267,10 +1359,6 @@ "messageformat": "АĐșырĐșы ĐŒĐ”ĐŽĐžĐ°ĐœŃ‹ ĐșÓ©Ń€ÒŻÒŻ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} ĐŒĐ”ĐœĐ”Đœ Đ±Đ°ŃˆŃ‚Đ°Đœ аяĐș ŃˆĐžŃ„Ń€Đ»Ó©Ó©ÒŁÒŻĐ·ĐŽÒŻĐœ ĐșĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐłŃƒĐœ тДĐșŃˆĐ”Ń€ÒŻÒŻ ÒŻŃ‡ÒŻĐœ Đ¶ĐŸĐłĐŸŃ€ŃƒĐŽĐ°ĐłŃ‹ ŃĐ°ĐœĐŽĐ°Ń€ĐŽŃ‹ Đ°Đ»Đ°Ń€ĐŽŃ‹Đœ Ń‚ÒŻĐ·ĐŒÓ©ĐłÒŻ ĐŒĐ”ĐœĐ”Đœ ŃĐ°Đ»Ń‹ŃˆŃ‚Ń‹Ń€Ń‹ÒŁŃ‹Đ·. Đ–ĐŸĐłĐŸŃ€ŃƒĐŽĐ°ĐłŃ‹ QR ĐșĐŸĐŽĐŽŃƒ сĐșĐ°ĐœĐŽĐ°ŃĐ°ÒŁŃ‹Đ· Đ±ĐŸĐ»ĐŸŃ‚.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ХОз бул Đ°ĐŽĐ°ĐŒ ĐŒĐ”ĐœĐ”Đœ эч ĐșĐ°ĐœĐŽĐ°Đč баĐčĐ»Đ°ĐœŃ‹ŃˆĐșа чыĐșĐșĐ°Đœ Đ¶ĐŸĐșсуз. ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒ Đ±ĐžŃ€ĐžĐœŃ‡Đž Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻ Đ¶Ó©ĐœÓ©Ń‚ÒŻĐ»ĐłÓ©ĐœĐŽÓ©Đœ ĐșĐžĐčĐžĐœ жДтĐșОлОĐșŃ‚ÒŻÒŻ Đ±ĐŸĐ»ĐŸŃ‚." }, @@ -1334,17 +1422,17 @@ "messageformat": "ĐœĐ°Đ°Đ»Ń‹ĐŒĐ°Ń‚", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ÓšŃ‡ÒŻŃ€ÒŻÒŻ", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ĐŽÒŻ Ó©Ń‡ÒŻŃ€ÒŻÒŻ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ĐœĐ°Đ”Đșто Ó©Ń‡ÒŻŃ€Ó©ŃÒŻĐ·Đ±ÒŻ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ĐŽÒŻ Ó©Ń‡ÒŻŃ€Ó©ŃÒŻĐ·Đ±ÒŻ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ĐœĐ°Đ”Đș бул Ń‚ÒŻĐ·ĐŒÓ©ĐșŃ‚Ó©Đœ Ó©Ń‡ÒŻŃ€ÒŻĐ»Ó©Ń‚.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Ушул ĐŒĐ°Đ”ĐșтДгО Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ бул Ń‚ÒŻĐ·ĐŒÓ©ĐșŃ‚Ó©Đœ Ó©Ń‡ÒŻŃ€ÒŻĐ»Ó©Ń‚. Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ĐŽÒŻ Ó©Ń‡ÒŻŃ€ĐłÓ©ĐœĐŽÓ©Đœ ĐșĐžĐčĐžĐœ ушул ĐŒĐ°Đ”Đșто таба аласыз.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ĐąĐŸĐżŃ‚ĐŸĐœ чыгуу", @@ -1438,6 +1526,14 @@ "messageformat": "Đ­ĐșĐž ĐŒĐ°Đ”ĐșŃ‚ĐžĐœ Ń‚Đ”ÒŁ Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»Ń‹ ушул жДргД бОрОĐșтОрОлЎО.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "Đ‘ŃƒĐ» Ń‚Đ”Đ»Đ”Ń„ĐŸĐœ ĐœĐŸĐŒĐ”Ń€ĐžĐœĐžĐœ ({phoneNumber}) ээсо - {conversationTitle}. Đ­ĐșÓ©Ó©ÒŁÓ©Ń€ Ń‚Đ”ÒŁ ушул Ń‚ĐŸĐżŃ‚ŃƒĐœ ĐŒÒŻŃ‡Ó©Đ»Ó©Ń€ÒŻŃÒŻĐ·: {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "({phoneNumber}) {conversationTitle} Ń‚Đ°Đ°ĐœĐŽŃ‹Đș.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ĐŠĐžŃ‚Đ°Ń‚Đ°Đ»Đ°ĐœĐłĐ°Đœ Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐŽÓ©ĐłÒŻ ŃÒŻŃ€Ó©Ń‚Ń‚ÒŻĐœ эсĐșОзО", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "КаĐčра Ń‡Đ°Đ»ŃƒŃƒ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Чалып Đ±Đ°ŃˆŃ‚ĐŸĐŸ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Чалууга ĐșĐŸŃˆŃƒĐ»ŃƒŃƒ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐŽĐ°ĐłŃ‹ Đ°ĐŽĐ°ĐŒĐŽĐ°Ń€ĐŽŃ‹Đœ ŃĐ°ĐœŃ‹ĐœĐ° Đ¶Đ°Ń€Đ°ŃˆĐ° ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœĐŽŃƒĐœ ÒŻĐœÒŻ Ó©Ń‡ÒŻŃ€ÒŻĐ»Ó©Ń‚", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Чалуу Đ±ĐžĐ»ĐŽĐžŃ€ĐŒĐ”Đ»Đ”Ń€Đž", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ĐžŃ€ŃƒĐœ Đ¶ĐŸĐș", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ĐšĐŸŃˆŃƒĐ»ŃƒŃƒ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Đ‘Đ°ŃˆŃ‚ĐŸĐŸ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Чалуу Ń‚ĐŸĐ»ŃƒĐș", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ° Ó©Ń‡ÒŻŃ€ÒŻĐ»ĐłÓ©Đœ", @@ -1621,10 +1725,6 @@ "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°ĐœŃ‹ ĐșÒŻĐčĐłÒŻĐ·ÒŻÒŻ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ÒźĐœÒŻĐœ басуу", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ Ó©Ń‡ÒŻŃ€ÒŻĐ»ĐłÓ©Đœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœĐŽŃƒĐœ ÒŻĐœÒŻĐœ чыгаруу", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Đ‘Ó©Đ»ÒŻŃˆÒŻÒŻ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ĐšÓ©Ń€ŃÓ©Ń‚ÒŻÒŻ Ó©Ń‡ÒŻŃ€ÒŻĐ»ĐłÓ©Đœ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ĐšÓ©Ń€ŃÓ©Ń‚ÒŻÒŻĐœÒŻ Ń‚ĐŸĐșŃ‚ĐŸŃ‚ŃƒŃƒ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Чалуу", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ĐąĐŸĐż өтө Ń‡ĐŸÒŁ Đ±ĐŸĐ»ĐłĐŸĐœĐŽŃƒĐșŃ‚Đ°Đœ, Đ°ĐœĐŽĐ°ĐłŃ‹Đ»Đ°Ń€ĐłĐ° чала албаĐčсыз", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ĐšŃ‹ÒŁĐłŃ‹Ń€ĐŸĐŸĐœŃƒ ĐžŃˆŃ‚Đ”Ń‚ÒŻÒŻ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ĐšŃ‹ÒŁĐłŃ‹Ń€ĐŽŃ‹ Ó©Ń‡ÒŻŃ€ÒŻÒŻ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ĐšŃ‹ÒŁĐłŃ‹Ń€ĐŽŃ‹ ĐșÒŻĐčĐłÒŻĐ·ÒŻÒŻ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Дагы ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ХОз", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°ÒŁŃ‹Đ· Ó©Ń‡ÒŻĐș", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒĐœ ĐșÓ©Ń€ÒŻÒŻ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ĐšĐŸĐŸĐżŃŃƒĐ·ĐŽŃƒĐș ĐșĐŸĐŽŃƒĐœ ĐșÓ©Ń€ÒŻÒŻ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,7 +2351,7 @@ "messageformat": "ĐąĐ”Đ»Đ”Ń„ĐŸĐœ ĐœĐŸĐŒĐ”Ń€Đž Đ°Đ»Ń‹ĐœĐ±Đ°Đč ĐșалЎы. Đ˜ĐœŃ‚Đ”Ń€ĐœĐ”Ń‚ĐșĐ” Ń‚ŃƒŃ‚Đ°ŃˆŃƒŃƒÒŁŃƒĐ·ĐŽŃƒ тДĐșŃˆĐ”Ń€ĐžĐż, ĐșаĐčра араĐșДт ĐșŃ‹Đ»Ń‹ÒŁŃ‹Đ·.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { + "icu:ToastManager__CannotEditMessage_24": { "messageformat": "ĐžÒŁĐŽĐŸĐŸĐ»ĐŸŃ€ бул Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻ Đ¶Ó©ĐœÓ©Ń‚ÒŻĐ»ĐłÓ©ĐœĐŽÓ©Đœ ĐșĐžĐčĐžĐœ 3 ŃĐ°Đ°Ń‚Ń‚Ń‹Đœ ĐžŃ‡ĐžĐœĐŽĐ” ĐșÒŻŃ‡ÒŻĐœÓ© ĐșОрДт.", "description": "Error message when you try to send an edit after message becomes too old" }, @@ -2480,6 +2596,14 @@ "messageformat": "Đ‘ŃƒĐ» Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻ Ó©Ń‡ÒŻŃ€ÒŻĐ»ĐłÓ©Đœ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "борĐșĐ”ĐŒĐ” ĐșÓ©Ń€ŃÓ©Ń‚ÒŻÒŻ ÒŻŃ‡ÒŻĐœ өтө Ń‡ĐŸÒŁ.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Кээ бОр торĐșĐ”ĐŒĐ”Đ»Đ”Ń€ өтө Ń‡ĐŸÒŁ Đ±ĐŸĐ»ĐłĐŸĐœĐŽŃƒĐșŃ‚Đ°Đœ, ĐșÓ©Ń€ÒŻĐœĐ±Ó©Đčт.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐŸ Ń‚ŃƒŃƒŃ€Đ°Đ»ŃƒŃƒ Ń‡ĐŸĐŸ-жаĐčы Đ°Đ»Ń‹ĐœĐ±Đ°Đč жатат", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal ŃŃ‹ĐœĐ°ĐŒŃ‹Đș Ń€Đ”Đ¶ĐžĐŒĐŽĐ” ĐłĐ°ĐœĐ°", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐ»Ó©Ń€ĐŽÒŻ Signal'ĐŽŃ‹Đœ ŃŃ‹ĐœĐ°ĐŒŃ‹Đș ĐșĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡ŃƒĐ»Đ°Ń€Ń‹ ĐłĐ°ĐœĐ° ĐŸÒŁĐŽĐŸĐč Đ°Đ»Ń‹ŃˆĐ°Ń‚. ЭгДр Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐœÒŻ ĐŸÒŁĐŽĐŸŃĐŸÒŁŃƒĐ·, ал Signal'ĐŽŃ‹Đœ ŃÒŁ аĐșырĐșы ŃŃ‹ĐœĐ°ĐŒŃ‹Đș ĐČĐ”Ń€ŃĐžŃŃŃ‹Đœ ĐșĐŸĐ»ĐŽĐŸĐœĐłĐŸĐœ Đ°ĐŽĐ°ĐŒĐŽĐ°Ń€ĐłĐ° ĐłĐ°ĐœĐ° ĐșÓ©Ń€ÒŻĐœÓ©Ń‚.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐœÒŻ ĐŸÒŁĐŽĐŸĐŸ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ЭгДр Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐœÒŻ ĐŸÒŁĐŽĐŸŃĐŸÒŁŃƒĐ·, ал Signal'ĐŽŃ‹Đœ ŃÒŁ аĐșырĐșы ĐČĐ”Ń€ŃĐžŃŃŃ‹Đœ ĐșĐŸĐ»ĐŽĐŸĐœĐłĐŸĐœ Đ°ĐŽĐ°ĐŒĐŽĐ°Ń€ĐłĐ° ĐłĐ°ĐœĐ° ĐșÓ©Ń€ÒŻĐœÓ©Ń‚. Алар ĐŸÒŁĐŽĐŸĐ»ĐłĐŸĐœ Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐœÒŻ ĐșÓ©Ń€Ó© Đ°Đ»Ń‹ŃˆĐ°Ń‚.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ĐšĐžŃ€ÒŻÒŻŃ‡ÒŻ ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Чыгуучу Đ°ŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Чыгуучу ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} сОзгД чалып жатат", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "КаĐčра баĐčĐ»Đ°ĐœŃ‹ŃˆŃ‹Đż жатасыз ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} ĐșОшО}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ĐŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Аягы", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Đ§Ń‹ĐłĐ°ĐŒ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ Ó©Ń‡ÒŻĐș", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ ĐșÒŻĐčÒŻĐș", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Чалып жатасыз", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ĐšŃ‹ÒŁĐłŃ‹Ń€ĐŽŃ‹ Ó©Ń‡ÒŻŃ€ÒŻÒŻ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐąŃƒŃƒŃ€Đ°Đ»ĐŸĐŸ", @@ -3468,13 +3668,25 @@ "messageformat": "ĐąĐŸĐ»ŃƒĐș эĐșŃ€Đ°ĐœĐŽŃƒŃƒ Ń‡Đ°Đ»ŃƒŃƒ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐąĐŸŃ€ ĐșÓ©Ń€ÒŻĐœÒŻŃˆÒŻĐœÓ© ĐșĐŸŃ‚ĐŸŃ€ŃƒĐ»ŃƒŃƒ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ĐšÓ©Ń€ÒŻĐœÒŻŃˆŃ‚ÒŻ Ó©Đ·ĐłÓ©Ń€Ń‚ÒŻÒŻ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ĐĄÒŻĐčĐ»Ó©ĐłÓ©Đœ Đ°ĐŽĐ°ĐŒĐŽŃ‹Đœ ĐșÓ©Ń€ÒŻĐœÒŻŃˆÒŻĐœÓ© ĐșĐŸŃ‚ĐŸŃ€ŃƒĐ»ŃƒŃƒ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ЧаĐșĐŒĐ°Đș ĐșÓ©Ń€ÒŻĐœÒŻŃˆÒŻ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "КапталĐșы тОлĐșĐ” ĐșÓ©Ń€ÒŻĐœÒŻŃˆÒŻ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Đ”ĐžĐœĐ°ĐŒĐžĐșŃ‚ĐžĐœ ĐșÓ©Ń€ÒŻĐœÒŻŃˆÒŻ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ĐšÓ©Ń€ÒŻĐœÒŻŃˆ Đ¶Đ°ÒŁŃ‹Ń€ĐŽŃ‹", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐŽĐ°Đœ чыгуу", @@ -3576,6 +3788,14 @@ "messageformat": "МаĐșул", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻ ĐŸÒŁĐŽĐŸĐ»Đ±ĐŸĐčт", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Đ‘ŃƒĐ» Đ±ĐžĐ»ĐŽĐžŃ€ÒŻÒŻĐœÒŻ {max,number} Đ¶ĐŸĐ»Ńƒ ĐłĐ°ĐœĐ° ĐŸÒŁĐŽĐŸĐč аласыз.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "КДчОрДсОз, бул sgnl:// ŃˆĐžĐ»Ń‚Đ”ĐŒĐ”ŃĐž учурЮа Signal Desktop Ń‚Đ°Ń€Đ°Đ±Ń‹ĐœĐ°Đœ ĐșĐŸĐ»ĐŽĐŸĐŸĐłĐŸ Đ°Đ»Ń‹ĐœĐ±Đ°Đčт.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡ŃƒĐœŃƒĐœ аты", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽĐ° ĐŒĐ°ŃĐ”Đ»Đ” жаралып, аĐșĐșĐ°ŃƒĐœŃ‚ŃƒÒŁŃƒĐ·ĐłĐ° баĐčĐ»Đ°ĐœĐ±Đ°Đč ĐșалЎы.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒ Đ°Ń‚Ń‹Đœ Ó©Ń‡ÒŻŃ€ÒŻÒŻ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹Đœ Ń‚ÒŻĐ·ÒŻÒŻ", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ĐșĐŸĐŽ жД ŃˆĐžĐ»Ń‚Đ”ĐŒĐ”", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹Đœ ĐșаĐčра ĐșĐŸŃŽŃƒ ĐșДрДĐș", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ĐœŃ‹Đœ ŃˆĐžĐ»Ń‚Đ”ĐŒĐ”ŃĐžĐœ ĐșаĐčра Ń‚ÒŻĐ·ÒŻÒŻ ĐșДрДĐș", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ Đ±Ó©Đ»ÒŻŃˆÒŻÒŁÒŻĐ·", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒ Đ°Ń‚Ń‹Đœ Ó©Ń‡ÒŻŃ€ÒŻÒŻ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Đ‘ŃƒĐ» ŃĐžĐ·ĐŽĐžĐœ ĐșĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ алып салып, башĐșа ĐșĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡ŃƒĐ»Đ°Ń€ĐłĐ° Đ°ĐœŃ‹ талап ĐșŃ‹Đ»ŃƒŃƒĐłĐ° ĐŒÒŻĐŒĐșÒŻĐœŃ‡ÒŻĐ»ÒŻĐș бДрДт. Алып саласызбы?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ÒŁŃ‹Đ·, ĐŸŃˆĐŸĐœĐŽĐŸĐč ŃĐ»Đ” QR ĐșĐŸĐŽŃƒÒŁŃƒĐ· ĐŒĐ”ĐœĐ”Đœ ŃˆĐžĐ»Ń‚Đ”ĐŒĐ”ÒŁĐžĐ· Ó©Ń‡ÒŻĐż Đșалат. БашĐșалар “{username}” ĐșĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹Đœ талап Đșыла Đ°Đ»Ń‹ŃˆĐ°Ń‚. Đ§Ń‹Đœ ŃĐ»Đ”Đ±Đž?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ОĐșŃƒŃĐ»Đ°Ń€ĐŽŃ‹ Đ±Ó©Đ»ÒŻŃˆÓ© албаĐč жД ĐșÓ©Ń€Ó© албаĐč Đșаласыз. ОĐșŃƒŃĐ»Đ°Ń€ĐŽĐ° жаĐșŃ‹ĐœĐŽĐ° Đ±Ó©Đ»ÒŻŃˆÒŻĐ»ĐłÓ©Đœ Đ¶Đ°ÒŁŃ‹Đ»Ń‹Đșтар Ўа Ó©Ń‡ÒŻĐż Đșалат.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "йОл", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "йОл", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ĐĄĐžŃŃ‚Đ”ĐŒĐ°ĐœŃ‹Đœ тОлО", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "йОлЎДрЎО ОзЎөө", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” Đ±ĐŸŃŽĐœŃ‡Đ° эч ĐœĐ”Ń€ŃĐ” Ń‚Đ°Đ±Ń‹Đ»ĐłĐ°Đœ Đ¶ĐŸĐș", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ĐšĐŸŃŽŃƒ", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Đ˜ŃˆŃ‚Đ”Ń‚ÒŻÒŻ ÒŻŃ‡ÒŻĐœ Signal'Юы Ó©Ń‡ÒŻŃ€ÒŻĐż ĐșÒŻĐčĐłÒŻĐ·ÒŻÒŁÒŻĐ·", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "йОлЎО Ó©Đ·ĐłÓ©Ń€Ń‚ÒŻÒŻ ÒŻŃ‡ÒŻĐœ ĐșĐŸĐ»ĐŽĐŸĐœĐŒĐŸĐœŃƒ Ó©Ń‡ÒŻŃ€ÒŻĐż, ĐșÒŻĐčĐłÒŻĐ·ÒŻÒŻ ĐșДрДĐș.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ÓšŃ‡ÒŻŃ€ÒŻĐż ĐșÒŻĐčĐłÒŻĐ·ÒŻÒŻ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} ĐČĐ”Ń€ŃĐžŃŃŃ‹ĐœĐ° Đ¶Đ°ÒŁŃ‹Ń€Ń‚ŃƒŃƒ жДтĐșОлОĐșŃ‚ÒŻÒŻ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ĐąŃƒŃƒŃ€Đ°Đ»ĐŸĐŸÒŁŃƒĐ·ĐŽŃƒ саĐșŃ‚ĐŸĐŸĐŽĐŸ Đșата ĐșДттО. ĐĄŃƒŃ€Đ°ĐœŃ‹Ń‡, ĐșаĐčра араĐșДт ĐșŃ‹Đ»Ń‹ÒŁŃ‹Đ·.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Đ‘ĐžĐ»ĐŽĐžŃ€ÒŻÒŻ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Дагы башĐșа стОлЎДр", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "БаштапĐșы абалга ĐșĐ”Đ»Ń‚ĐžŃ€ÒŻÒŻ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Đ‘ÒŻŃ‚Ń‚ÒŻ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ĐšĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡ŃƒĐœŃƒĐœ Đ°Ń‚Ń‹ĐœŃ‹Đœ ŃˆĐžĐ»Ń‚Đ”ĐŒĐ”ŃĐžĐœĐžĐœ Ń‚ÒŻŃÒŻ, {total,number} ĐžŃ‡ĐžĐœĐ”Đœ {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "QR ĐșĐŸĐŽŃƒÒŁŃƒĐ·ĐŽŃƒ ĐșаĐčра ĐșĐŸĐčŃĐŸÒŁŃƒĐ·, учурЮагы QR ĐșĐŸĐŽŃƒÒŁŃƒĐ· ĐžŃˆŃ‚Đ”Đ±Đ”Đč Đșалат.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ĐšĐžĐ»Ń‚Đ”ĐŒĐ” ĐșаĐčра Ń‚ÒŻĐ·ÒŻĐ»ÒŻÒŻĐŽÓ©...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR ĐșĐŸĐŽ Đ¶Đ°ĐœĐ° ŃˆĐžĐ»Ń‚Đ”ĐŒĐ” ĐșĐŸŃŽĐ»ĐłĐ°Đœ Đ¶ĐŸĐș. БаĐčĐ»Đ°ĐœŃ‹ŃˆŃ‹ÒŁŃ‹Đ·ĐŽŃ‹ тДĐșŃˆĐ”Ń€ĐžĐż, ĐșаĐčталап ĐșÓ©Ń€ÒŻÒŁÒŻĐ·.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Signal'Ўа ĐșĐŸĐ»ĐŽĐŸĐœŃƒŃƒŃ‡Ńƒ Đ°Ń‚Ń‹ÒŁŃ‹Đ·ĐŽŃ‹ ĐșĐŸŃŽÒŁŃƒĐ·", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "ĐŸÒŁĐŽĐŸĐ»ĐłĐŸĐœ", + "messageformat": "ĐžÒŁĐŽĐŸĐ»ĐłĐŸĐœ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "КаĐčра Đ¶Ó©ĐœÓ©Ń‚ÒŻÒŻ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Дагы", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐ»Đ°Ń€", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Đ–Đ°ÒŁŃ‹ Ń‡Đ°Đ»ŃƒŃƒ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Đ–Đ°ÒŁŃ‹ Ń‡Đ°Đ»ŃƒŃƒ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Дагы", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐ»Đ°Ń€ Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»Ń‹Đœ Ń‚Đ°Đ·Đ°Đ»ĐŸĐŸ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Đ§Đ°Đ»ŃƒŃƒĐ»Đ°Ń€ Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»Ń‹Đœ тазалаĐčсызбы?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ĐŁŃˆŃƒĐœŃƒ ĐŒĐ”ĐœĐ”Đœ, Ń‡Đ°Đ»ŃƒŃƒĐ»Đ°Ń€ Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»Ń‹ Đ±ĐžŃ€ĐŸŃ‚ĐŸĐ»ĐŸ Ó©Ń‡ÒŻĐż Đșалат", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ĐąĐ°Đ·Đ°Đ»ĐŸĐŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Чалуу Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»Ń‹ Ń‚Đ°Đ·Đ°Đ»Đ°ĐœĐŽŃ‹", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ĐšÓ©Ń€ÒŻÒŻ жД чалып Đ±Đ°ŃˆŃ‚ĐŸĐŸ ÒŻŃ‡ÒŻĐœ Đ±Đ°ŃŃ‹ÒŁŃ‹Đ·", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ИзЎөө", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”ĐœĐŽĐ”Ń€ Đ±ĐŸŃŽĐœŃ‡Đ° Оргөө", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ÓšŃ‚ÒŻÒŻ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Эч ĐœĐ”Ń€ŃĐ” Đ¶ĐŸĐș. Đ”ĐŸŃŃƒÒŁŃƒĐ·ĐłĐ° чалып Đ±Đ°ŃˆŃ‚Đ°ÒŁŃ‹Đ·.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” Đ±ĐŸŃŽĐœŃ‡Đ° эч ĐœĐ”Ń€ŃĐ” Ń‚Đ°Đ±Ń‹Đ»ĐłĐ°Đœ Đ¶ĐŸĐș", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ĐšĐ”Đ»ĐłĐ”Đœ Ń‡Đ°Đ»ŃƒŃƒĐ»Đ°Ń€", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ЧыĐșĐșĐ°Đœ Ń‡Đ°Đ»ŃƒŃƒĐ»Đ°Ń€", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ĐąĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Эч ĐœĐ”Ń€ŃĐ” Đ¶ĐŸĐș.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” Đ±ĐŸŃŽĐœŃ‡Đ° эч ĐœĐ”Ń€ŃĐ” Ń‚Đ°Đ±Ń‹Đ»ĐłĐ°Đœ Đ¶ĐŸĐș", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Чыгуучу Đ°ŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ} other {ĐšĐ”Đ»ÒŻÒŻŃ‡ÒŻ Đ°ŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ}}} Video {{direction, select, Outgoing {Чыгуучу ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ} other {ĐšĐžŃ€ÒŻÒŻŃ‡ÒŻ ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ}}} Group {{direction, select, Outgoing {Чыгуучу Ń‚ĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒ} other {ĐšĐ”Đ»ÒŻÒŻŃ‡ÒŻ Ń‚ĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒ}}} other {{direction, select, Outgoing {Чыгуучу Ń‡Đ°Đ»ŃƒŃƒ} other {ĐšĐžŃ€ÒŻÒŻŃ‡ÒŻ Ń‡Đ°Đ»ŃƒŃƒ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Кабыл Đ°Đ»Ń‹ĐœĐ±Đ°ĐłĐ°Đœ Đ°ŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ} Video {Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ} Group {Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ Ń‚ĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒ} other {Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ Ń‡Đ°Đ»ŃƒŃƒ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ Đ°ŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ} Video {Đ–ĐŸĐŸĐżŃŃƒĐ· ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ} Group {Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ Ń‚ĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒ} other {Đ–ĐŸĐŸĐż Đ±Đ”Ń€ĐžĐ»Đ±Đ”ĐłĐ”Đœ Ń‡Đ°Đ»ŃƒŃƒ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ЧДтĐșĐ” ĐșĐ°ĐłŃ‹Đ»ĐłĐ°Đœ Đ°ŃƒĐŽĐžĐŸ Ń‡Đ°Đ»ŃƒŃƒ} Video {ЧДтĐșĐ” ĐșĐ°ĐłŃ‹Đ»ĐłĐ°Đœ ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒ} Group {ЧДтĐșĐ” ĐșĐ°ĐłŃ‹Đ»ĐłĐ°Đœ Ń‚ĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒ} other {ЧДтĐșĐ” ĐșĐ°ĐłŃ‹Đ»ĐłĐ°Đœ Ń‡Đ°Đ»ŃƒŃƒ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {Дагы {count,number} Đ°ĐŽĐ°ĐŒ жазып жатат.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Đ–Đ°ÒŁŃ‹Đ»Ń‹Đșтар", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "МаĐčЎа-барат Ó©Đ·ĐłÓ©Ń€ÒŻÒŻĐ»Ó©Ń€ĐŽÒŻ ĐșОргОзОп, ĐŒÒŻŃ‡ÒŻĐ»ÒŻŃˆŃ‚ÒŻĐșŃ‚Ó©Ń€ĐŽÒŻ ĐŸÒŁĐŽĐŸĐż, ĐșĐŸĐ»ĐŽĐŸĐœĐŒĐŸĐœŃƒĐœ ĐžŃˆŃ‚Đ”ŃˆĐžĐœ жаĐșшыртып жатабыз. Signal'Юы ĐșĐŸĐ»ĐŽĐŸĐœĐłĐŸĐœŃƒÒŁŃƒĐ· ÒŻŃ‡ÒŻĐœ Ń‡ĐŸÒŁ Ń€Đ°Ń…ĐŒĐ°Ń‚!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Đ‘ŃƒĐ» ĐČĐ”Ń€ŃĐžŃĐŽĐ° Đ°ŃƒĐŽĐžĐŸ Đ¶Đ°ĐœĐ° ĐČĐžĐŽĐ”ĐŸ Ń‡Đ°Đ»ŃƒŃƒĐ»Đ°Ń€ жаĐșшырып, ĐŽĐŸĐșŃƒĐŒĐ”ĐœŃ‚Ń‚Đ”Ń€ĐłĐ” Ó©Đ·ĐłÓ©Ń€ÒŻÒŻĐ»Ó©Ń€ ĐșОргОзОлЎО (Ń‡ĐŸÒŁ Ń€Đ°Ń…ĐŒĐ°Ń‚, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Đ­ĐŒĐž ŃĐžŃŃ‚Đ”ĐŒĐ°ĐœŃ‹Đœ ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€ĐžĐœ өзгөртпөĐč туруп, Signal'ĐŽŃ‹Đœ Ń‚ĐžĐ»ĐžĐœ өзгөртө аласыз (Signal ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€Đž > ĐšÓ©Ń€ÒŻĐœÒŻŃˆÒŻ > йОл)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ĐąĐŸĐżĐșĐŸ ĐșĐžĐŒĐŽĐžŃ€ Đ±ĐžŃ€Ó©Ó©ĐœÒŻĐœ ĐșĐŸŃˆŃƒĐ»ĐłĐ°ĐœŃ‹Đœ ĐșĐ°Đ±Đ°Ń€Đ»Đ°ĐłĐ°Đœ Ń‚ĐŸĐżŃ‚ŃƒĐœ Đ¶Đ°ÒŁŃ‹Đ»Ń‹ĐșŃ‚Đ°Ń€Ń‹Đœ ĐșөрсөтĐșÓ©Đœ аĐčŃ€Ń‹ĐŒ Đ±ĐžĐ»ĐŽĐžŃ€ĐŒĐ” ŃÒŻŃ€Ó©Ń‚Ń‡Ó©Đ»Ó©Ń€ÒŻ Ó©Đ·ĐłÓ©Ń€ĐŽÒŻ. ĐœŃƒŃ€ŃƒĐœĐșу ŃÒŻŃ€Ó©Ń‚Ń‡Ó©Đ»Ó©Ń€ ĐšÒŻÒŁÒŻŃ€Ń‚ Ń‚Đ”ĐŒĐ°ĐłĐ° Ń‹ÒŁĐłĐ°Đčлашса, Đ¶Đ°ÒŁŃ‹ ŃÒŻŃ€Ó©Ń‚Ń‡Ó©Đ»Ó©Ń€ ĐŸŃˆĐŸĐ» ĐšÒŻÒŁÒŻŃ€Ń‚ Ń‚Đ”ĐŒĐ°ĐœŃ‹Đœ ĐžŃ‡ĐžĐœĐŽĐ” жаралЎы." + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOS Ń‚ÒŻĐ·ĐŒÓ©ĐșŃ‚Ó©Ń€ÒŻĐœĐŽÓ© Ń‡Đ°Đ»ŃƒŃƒ Đ»ĐŸĐ±Đ±ĐžŃĐžĐœĐ” ĐșĐŸŃˆŃƒĐ»ŃƒĐż жатĐșĐ°ĐœĐŽĐ°ĐłŃ‹ ĐșĐžŃ‡ĐžĐœĐ”ĐșĐ”Đč ĐșĐ”Ń‡ĐžĐłÒŻÒŻĐœÒŻ ĐŸÒŁĐŽĐŸĐŽŃƒĐș." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ĐšĐžĐŒĐŽĐžŃ€ бОрөө Ń‚ĐŸĐżŃ‚ŃƒĐș Ń‡Đ°Đ»ŃƒŃƒĐłĐ° ĐșĐŸŃˆŃƒĐ»ĐłĐ°ĐœĐŽĐ° жД Đ°ĐœĐŽĐ°Đœ чыĐșĐșĐ°ĐœĐŽĐ° тоĐčĐžŃˆŃ‚ÒŻÒŻ Đ°ĐœĐžĐŒĐ°Ń†ĐžŃ ĐșÓ©Ń€ÒŻĐœÓ©Ń‚. Đ”ĐŸŃŃƒÒŁŃƒĐ·ĐŽŃƒĐœ Đ¶ÒŻĐ·ÒŻ ĐșÓ©Ń€ÒŻĐœŃÓ©, ал ĐșĐŸĐŸĐŒĐŽŃƒĐș ĐșыĐčĐŒŃ‹Đ» Đ±ĐŸĐ»ĐŸŃ‚." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ĐœĐ°Đ”ĐșŃ‚ĐžĐœ ĐżĐ°Ń€Đ°ĐŒĐ”Ń‚Ń€Đ»Đ”Ń€ĐžĐœĐ” Ó©Ń‚ÒŻÒŻ жД Đ°ĐœĐŽĐ°ĐłŃ‹ Đ¶Đ°ŃˆŃ‹Ń€Ń‹Đ»ĐłĐ°Đœ Ń‚Đ°Ń€Đ¶Ń‹ĐŒĐ°Đ»ĐŽĐ°Ń€ĐŽŃ‹ ĐșÓ©Ń€ÒŻÒŻ ÒŻŃ‡ÒŻĐœ ĐŒĐ°Đ”ĐșтДгО ĐżŃ€ĐŸŃ„ĐžĐ»ĐŽĐžĐœ ŃÒŻŃ€Ó©Ń‚ÒŻĐœ жД Ń‚ĐŸĐżŃ‚ŃƒĐș аĐČатарЮы басып ĐșĐŸŃŽÒŁŃƒĐ·. Đ§ĐŸÒŁ Ń€Đ°Ń…ĐŒĐ°Ń‚, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/lt-LT/messages.json b/_locales/lt-LT/messages.json index 6fb3f7bc86..c819cd88f8 100644 --- a/_locales/lt-LT/messages.json +++ b/_locales/lt-LT/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "DuomenĆł bazės klaida", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Aptikta duomenĆł bazės klaida. Klaidą galite nukopijuoti ir kreiptis pagalbos ÄŻ „Signal“ klientĆł aptarnavimo komandą. Jei pasinaudoti „Signal“ jums reikia skubiai, galite iĆĄtrinti savo duomenis ir bandyti iĆĄ naujo.\n\nSusisiekite su klientĆł aptarnavimo komanda apsilankydami čia: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "IĆĄtrinti visus duomenis ir paleisti iĆĄ naujo", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "IĆĄtrinti duomenis ir paleisti iĆĄ naujo", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "IĆĄtrinti visus duomenis visam laikui?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Visa tavo ĆŸinučiĆł istorija ir ÄŻraĆĄai bus iĆĄtrinti iĆĄ ĆĄio ÄŻrenginio visam laikui. Galėsi naudoti „Signal“ ĆĄiame ÄŻrenginyje po to, kai iĆĄ naujo susiesi. IĆĄ tavo telefono nebus iĆĄtrinti jokie duomenys.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Tavo duomenĆł bazės versija neatitinka ĆĄios „Signal“ versijos. Äźsitikink, kad savo kompiuteryje bandai atidaryti naujausią „Signal“ versiją.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Failas", @@ -300,6 +316,70 @@ "messageformat": "Pokalbiai", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "KaĆŸkas nutiko su tavo naudotojo vardu, jis nebėra priskirtas tavo paskyrai. Gali pabandyti jÄŻ nustatyti dar kartą arba pasirinkti naują.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Tvarkyti dabar", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "KaĆŸkas negerai su tavo QR kodu ir naudotojo vardo nuoroda, jie nebegalioja. Sukurk naują nuorodą bendrinimui su kitais.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Tvarkyti dabar", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Rodyti skirtukus", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Slėpti skirtukus", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Äźvyko klaida", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "NeperskaitytĆł: {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "PaĆŸymėta kaip neskaityta", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Pokalbiai", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Skambučiai", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Istorijos", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Nustatymai", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Atnaujinti Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profilis", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Atgal", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ć ie pokalbiai yra archyvuoti ir atsiras tarp gautĆłjĆł tik jei bus gauta naujĆł ĆŸinučiĆł.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Vis tiek skambinti", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Vis tiek prisijungti", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Tęsti skambutÄŻ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Saugumo numeriai atnaujinami.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "SuĆŸinoti daugiau", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Ankstesnis saugumo numeris", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Kitas saugumo numeris", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Saugumo numerio versija, {index,number} iĆĄ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Ćœymėti kaip patvirtintą", @@ -663,33 +747,41 @@ "messageformat": "IĆĄvalyti patvirtinimą", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Jei nori patikrinti, ar pokalbis su {name} yra visiĆĄkai uĆŸĆĄifruotas, palygink skaičius virĆĄuje ir paĆĄnekovo ÄŻrenginyje. PaĆĄnekovas taip pat gali nuskaityti tavo kodą savo ÄŻrenginiu.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "SuĆŸinoti daugiau", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Jei nori patikrinti, ar pokalbis su {name} yra visiĆĄkai uĆŸĆĄifruotas, palygink skaičius virĆĄuje ir paĆĄnekovo ÄŻrenginyje. Jei jie nesutampa, pabandyk kitą saugumo numeriĆł porą. Tereikia vienos sutampančios poros.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Jei nori patikrinti, ar pokalbis su {name} yra visiĆĄkai uĆŸĆĄifruotas, palygink skaičius virĆĄuje ir paĆĄnekovo ÄŻrenginyje. PaĆĄnekovas taip pat gali nuskaityti tavo kodą savo ÄŻrenginiu.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Saugumo numeriĆł pakeitimai", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Saugumo numeriai atnaujinami pereinamuoju laikotarpiu, kad ÄŻjungtume bĆ«simas „Signal“ privatumo funkcijas.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Jei nori patikrinti saugumo numerius, palygink spalvotoje kortelėje rodomus numerius savo ir paĆĄnekovo ÄŻrenginyje. Jei jie nesutampa, pabandyk kitą saugumo numeriĆł porą. Tereikia vienos sutampančios poros.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Reikia pagalbos?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Supratau", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Saugumo numeris su ĆĄiuo asmeniu bus sukurtas tada, kai vienas kitam paraĆĄysite ĆŸinutes.", @@ -1267,10 +1359,6 @@ "messageformat": "Rodyti paskiausią mediją", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Jei nori patikrinti pokalbio su {name} visiĆĄko uĆŸĆĄifravimo saugumą, palygink skaičius virĆĄuje ir paĆĄnekovo ÄŻrenginyje. PaĆĄnekovas taip pat gali nuskaityti virĆĄuje esantÄŻ QR kodą.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "JĆ«s su ĆĄiuo adresatu dar nesate apsikeitę jokiomis ĆŸinutėmis. JĆ«sĆł saugumo numeris bus prieinamas po pirmosios ĆŸinutės." }, @@ -1334,17 +1422,17 @@ "messageformat": "Informacija", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "IĆĄtrinti", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "IĆĄtrinti ĆŸinutes", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "IĆĄtrinti pokalbÄŻ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "IĆĄtrinti ĆŸinutes?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Ć is pokalbis bus iĆĄtrintas iĆĄ ĆĄio ÄŻrenginio.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Ć io pokalbio ĆŸinutės bus iĆĄtrintos iĆĄ ĆĄio ÄŻrenginio. Net kai iĆĄtrinsi ĆŸinutes, vis tiek galėsi ieĆĄkoti ĆĄio pokalbio.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "IĆĄeiti iĆĄ grupės", @@ -1438,6 +1526,14 @@ "messageformat": "AbiejĆł pokalbiĆł ĆŸinučiĆł istorija buvo sujungta čia.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} priklauso {conversationTitle}. Abu esate ĆĄioje grupėje: {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} priklauso {conversationTitle}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Paveikslo iĆĄ cituotos ĆŸinutės miniatiĆ«ra", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Skambinti vėl", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Pradėti skambutÄŻ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Prisijungti prie skambučio", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofonas iĆĄjungtas dėl skambučio dalyviĆł skaičiaus", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "SkambučiĆł praneĆĄimai", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Skambutis yra pilnas", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Prisijungti", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Pradėti", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Skambutis pilnas", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera iĆĄjungta", @@ -1621,10 +1725,6 @@ "messageformat": "Äźjungti kamerą", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Nutildyti", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofonas iĆĄjungtas", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Äźjungti mikrofoną", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Bendrinti", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Pristatinėjimas iĆĄjungtas", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Stabdyti pristatinėjimą", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Skambinti", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupė yra per didelė, kad bĆ«tĆł skambinama dalyviams.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Äźjungti skambinimą", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "IĆĄjungti skambėjimą", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Äźjungti skambėjimą", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Daugiau parinkčiĆł", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "JĆ«s", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "JĆ«sĆł kamera iĆĄjungta", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Rodyti saugumo numerÄŻ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "SiĆłsk ĆŸinutę", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Rodyti saugumo numerÄŻ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Nepavyko gauti telefono numerio. Patikrinkite interneto ryĆĄÄŻ ir bandykite dar kartą.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Redaguoti leidĆŸiama 3 valandas nuo ĆŸinutės iĆĄsiuntimo momento.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Redaguoti galima ne vėliau kaip per 24 val. nuo ĆĄios ĆŸinutės iĆĄsiuntimo.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ć i ĆŸinutė buvo iĆĄtrinta.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Priedas nerodomas, nes per didelis.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Kai kurie priedai nerodomi, nes per dideli.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nepavyko gauti paramos informacijos", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Tik „Signal“ beta versijai", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Redaguoti ĆŸinutes gali tik „Signal“ beta versijos naudotojai. Jei redaguosi ĆŸinutę, tai bus matoma tik naujausią „Signal“ beta versiją naudojantiems ĆŸmonėms.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Redaguoti ĆŸinutę", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Jei redaguosi ĆŸinutę, tai bus matoma tik naujausias „Signal“ versijas naudojantiems ĆŸmonėms. Jie matys, kad redagavai ĆŸinutę.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Gaunamasis vaizdo skambutis
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "IĆĄsiunčiamasis balso skambutis", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "IĆĄsiunčiamasis vaizdo skambutis", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "Jums skambina {ringer}", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Jungiamasi iĆĄ naujo
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} ĆŸmogus} few {{count,number} ĆŸmonės} many {{count,number} ĆŸmoniĆł} other {{count,number} ĆŸmogus}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Garso skambutis", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Baigti", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "IĆĄeiti", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofonas iĆĄjungtas", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofonas ÄŻjungtas", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Skambėjimas ÄŻjungtas", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Skambėjimas iĆĄjungtas", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Nustatymai", @@ -3468,13 +3668,25 @@ "messageformat": "Skambutis visame ekrane", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Perjungti ÄŻ tinklelio rodinÄŻ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Keisti rodinÄŻ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Perjungti ÄŻ kalbėtojo rodinÄŻ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Tinklelio rodinys", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Ć oninė juosta", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Kalbantysis", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Rodinys atnaujintas", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "IĆĄeiti iĆĄ skambučio", @@ -3576,6 +3788,14 @@ "messageformat": "Gerai", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Ćœinutės redaguoti negalima", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Ć iai ĆŸinutei galima atlikti tik {max,number} pakeitimĆł.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Atleiskite, ta sgnl:// nuoroda neturi prasmės!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Naudotojo vardas", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "KaĆŸkas nutiko su tavo naudotojo vardu, jis nebėra priskirtas tavo paskyrai.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "IĆĄtrinti naudotojo vardą", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Susikurti naudotojo vardą", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kodas arba nuoroda", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Naudotojo vardą reikia nustatyti iĆĄ naujo", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Naudotojo vardo nuorodą reikia nustatyti iĆĄ naujo", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Bendrinti savo naudotojo vardą", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "IĆĄtrinti naudotojo vardą", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Tai paĆĄalins tavo naudotojo vardą ir jÄŻ galės uĆŸimti kiti naudotojai. Ar esi tikras?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Tavo naudotojo vardas bus paĆĄalintas, ir QR kodas bei nuoroda nebeveiks. Naudotojo vardą „{username}“ galės pasirinkti kiti. Ar tikrai to nori?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Nebegalėsi nei bendrinti, nei ĆŸiĆ«rėti istorijĆł. Tai, ką pastaruoju metu bendrinai ĆĄioje istorijoje, taip pat bus iĆĄtrinta.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Kalba", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Kalba", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistemos kalba", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "IeĆĄkoti kalbĆł", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "PaieĆĄka „{searchTerm}“ be rezultatĆł", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Nustatyti", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Paleisk „Signal“ iĆĄ naujo pakeitimams pritaikyti", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Norint pakeisti kalbą, programėlę reikia paleisti iĆĄ naujo.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Paleisti iĆĄ naujo", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Yra prieinamas atnaujinimas ÄŻ versiją {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ÄźraĆĄant jĆ«sĆł nustatymus, ÄŻvyko klaida. Bandykite dar kartą.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Ćœinutė", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Daugiau stiliĆł", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Atstatyti", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Atlikta", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Naudotojo vardo nuorodos spalva, {index,number} iĆĄ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Jei nustatysi savo QR kodą iĆĄ naujo, esamas QR kodas ir nuoroda nebeveiks.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Nuoroda nustatoma iĆĄ naujo
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kodas ir nuoroda nenustatyti. Patikrink tinklo ryĆĄÄŻ ir bandyk dar kartą.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Sukurk savo „Signal“ naudotojo vardą", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "redaguota", + "messageformat": "Redaguota", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "SiĆłsti dar kartą", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Daugiau veiksmĆł", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Skambučiai", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Naujas skambutis", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Naujas skambutis", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Daugiau veiksmĆł", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "IĆĄvalyti skambučiĆł istoriją", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "IĆĄvalyti skambučiĆł istoriją?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Visa skambučiĆł istorija bus iĆĄtrinta visam laikui", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "IĆĄvalyti", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "SkambučiĆł istorija iĆĄvalyta", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Spustelėk perĆŸiĆ«rėti ar pradėti skambutÄŻ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "IeĆĄkoti", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtruoti pagal praleistus", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Perjungti", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "NesenĆł skambučiĆł nėra. Pradėk nuo skambučio draugui.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "PaieĆĄka „{query}“ be rezultatĆł", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Gaunamasis", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "IĆĄsiunčiamieji", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Praleisti", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Grupės skambutis", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "NesenĆł pokalbiĆł nėra.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "PaieĆĄka „{query}“ be rezultatĆł", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {IĆĄsiunčiamasis balso skambutis} other {Gaunamasis balso skambutis}}} Video {{direction, select, Outgoing {IĆĄsiunčiamasis vaizdo skambutis} other {Gaunamasis vaizdo skambutis}}} Group {{direction, select, Outgoing {IĆĄsiunčiamasis grupės skambutis} other {Gaunamasis grupės skambutis}}} other {{direction, select, Outgoing {IĆĄsiunčiamasis skambutis} other {Gaunamasis skambutis}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Praleistas balso skambutis} Video {Praleistas vaizdo skambutis} Group {Praleistas grupės skambutis} other {Praleistas skambutis}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Neatsakytas balso skambutis} Video {Neatsakytas vaizdo skambutis} Group {Neatsakytas grupės skambutis} other {Neatsakytas skambutis}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Atmestas balso skambutis} Video {Atmestas vaizdo skambutis} Group {Atmestas grupės skambutis} other {Atmestas skambutis}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ĆŸmogus raĆĄo.} few {{count,number} ĆŸmonės raĆĄo.} many {{count,number} ĆŸmoniĆł raĆĄo.} other {{count,number} ĆŸmoniĆł raĆĄo.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Kas naujo", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "SmulkĆ«s patobulinimai, klaidĆł pataisymai ir veikimo pagerinimas. AčiĆ«, kad naudoji „Signal“!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Äź ĆĄÄŻ atnaujinimą ÄŻeina keli balso ir vaizdo skambučiĆł patobulinimai bei keletas dokumentacijos naujiniĆł (ačiĆ«, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Dabar programėlėje „Signal“ galima pakeisti pasirinktą kalbą nekeičiant savo sistemos nustatymĆł („Signal“ nustatymai > IĆĄvaizda > Kalba)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Pakeitėme kai kurias grupės praneĆĄimĆł piktogramas." + "icu:WhatsNew__v6.39--1": { + "messageformat": "IĆĄtaisėme trumpą uĆŸdelsimą, kurÄŻ kartais patirdavo „macOS“ ÄŻrenginiĆł naudotojai laukdami prijungimo prie skambučio." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Pataisėme vaizdo ÄŻraĆĄĆł plyteliĆł perėjimo animaciją, kai kas nors prisijungia arba iĆĄeina iĆĄ grupės skambučio. Jei pamatote draugo veidą, atsirandantÄŻ rodinyje, taip ir turi bĆ«ti." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Dabar pokalbio antraĆĄtėje galite spustelėti profilio nuotrauką arba grupės avatarą, kad greitai pasiektumėte pokalbio nustatymus arba perĆŸiĆ«rėtumėte nematytas to pokalbio istorijas. AčiĆ«, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/lv-LV/messages.json b/_locales/lv-LV/messages.json index ad10bcce04..c653fd460c 100644 --- a/_locales/lv-LV/messages.json +++ b/_locales/lv-LV/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Datu bāzes kÄŒĆ«da", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Radusies datubāzes kÄŒĆ«da. Varat nokopēt kÄŒĆ«das aprakstu un sazināties ar Signal atbalsta dienestu, lai novērstu problēmu. Ja nepiecieĆĄams izmantot Signal nekavējoties, varat dzēst savus datus un sākt no jauna.\n\nSazinieties ar atbalsta dienestu, apmeklējot vietni: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Dzēst visus datus un restartēt", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Dzēst datus un restartēt", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Vai neatgriezeniski dzēst visus datus?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Visa ziƆojumu vēsture un multivides faili tiks neatgriezeniski dzēsti no ĆĄÄ«s ierÄ«ces. Ć ajā ierÄ«cē Signal varēsiet lietot pēc tās atkārtotas pievienoĆĄanas. Veicot ĆĄo darbÄ«bu, dati netiks dzēsti no jĆ«su tālruƆa.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "JĆ«su datubāzes versija neatbilst ĆĄai Signal versijai. Pārliecinieties, vai datorā atvērta jaunākā Signal versija.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fails", @@ -300,6 +316,70 @@ "messageformat": "Sarunas", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Radās problēma ar jĆ«su lietotāja vārdu. Tas vairs nav piesaistÄ«ts jĆ«su kontam. Varat mēģināt to iestatÄ«t vēlreiz vai izvēlēties jaunu.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Labot", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Radās problēma saistÄ«bā ar jĆ«su QR kodu un lietotāja vārda saiti. Tā vairs nav derÄ«ga. Izveidojiet jaunu saiti, ko kopÄ«got ar citiem.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Labot", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "RādÄ«t cilnes", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Paslēpt cilnes", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ir radusies kÄŒĆ«da", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} nelasÄ«tas", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "AtzÄ«mēta kā nelasÄ«ta", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Sarunas", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Zvani", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stāsti", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "IestatÄ«jumi", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Aktualizēt Signālu", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profils", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "AtpakaÄŒ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ć Ä«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" @@ -576,6 +656,10 @@ "messageformat": "Vienalga zvanÄ«t", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Tomēr pievienoties", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Turpināt zvanu", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "DroĆĄÄ«bas numuri tiek atjaunināti.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "LasÄ«t vairāk", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Iepriekơējais droĆĄÄ«bas numurs", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Nākamais droĆĄÄ«bas numurs", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "DroĆĄÄ«bas numura versija, {index,number}. no {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "AtzÄ«mēt kā apstiprinātu", @@ -663,33 +747,41 @@ "messageformat": "Dzēst verifikāciju", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Lai pārbaudÄ«tu pilnÄ«gu ĆĄifrēơanu sarunai ar {name}, salÄ«dziniet augstāk redzamos ciparus ar ĆĄÄ«s personas ierÄ«cē redzamajiem. Ć is sarunu biedrs var arÄ« skenēt jĆ«su kodu ar savu ierÄ«ci.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Uzzināt vairāk", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Lai pārbaudÄ«tu pilnÄ«gu ĆĄifrēơanu sarunai ar {name}, saskaƆojiet augstāk redzamo krāsu karti ar ĆĄÄ«s personas ierÄ«cē redzamo un salÄ«dziniet numurus. Ja tie nesakrÄ«t, pavelciet un izmēģiniet otru droĆĄÄ«bas numuru pāri. Ir jāsakrÄ«t tikai vienam pārim.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Lai pārbaudÄ«tu pilnÄ«gu ĆĄifrēơanu sarunai ar {name}, salÄ«dziniet augstāk redzamos ciparus ar ĆĄÄ«s personas ierÄ«cē redzamajiem. Ć is sarunu biedrs var arÄ« skenēt jĆ«su kodu ar savu ierÄ«ci.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "DroĆĄÄ«bas numuru izmaiƆas", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "DroĆĄÄ«bas numuri tiek atjaunināti pārejas periodā, lai nodroĆĄinātu gaidāmās privātuma funkcijas pakalpojumā Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Lai pārbaudÄ«tu droĆĄÄ«bas numurus, saskaƆojiet krāsu karti ar kontaktpersonas ierÄ«cē redzamo. Ja tie nesakrÄ«t, pavelciet un izmēģiniet otru droĆĄÄ«bas numuru pāri. Ir jāsakrÄ«t tikai vienam pārim.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "NepiecieĆĄama palÄ«dzÄ«ba?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Skaidrs", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "DroĆĄÄ«bas numurs ar ĆĄo personu tiks izveidots pēc tam, kad bĆ«siet nosĆ«tÄ«juĆĄi viens otram ziƆas.", @@ -1267,10 +1359,6 @@ "messageformat": "SkatÄ«t jaunāko multivides saturu", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Lai pārbaudÄ«tu pilnÄ«gās ĆĄifrēơanas droĆĄÄ«bu sarunai ar {name}, salÄ«dziniet augstāk redzamos ciparus ar ĆĄÄ«s personas ierÄ«cē redzamajiem. Ć is sarunu biedrs var arÄ« noskenēt augstāk redzamo QR kodu.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "JĆ«s vēl neesat apmainÄ«jies ar ziƆām ar ĆĄo kontaktpersonu. JĆ«su droĆĄÄ«bas numurs ar viƆu bĆ«s pieejams pēc pirmās ziƆas." }, @@ -1334,17 +1422,17 @@ "messageformat": "Informācija", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Dzēst", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ZiƆu dzēơana", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Vai dzēst sarunu?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Vai dzēst ziƆas?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Ć Ä« tērzēơana tiks dzēsta no ĆĄÄ«s ierÄ«ces.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Ć Ä«s sarunas ziƆas tiks dzēstas no ĆĄÄ«s ierÄ«ces. Pēc ziƆu dzēơanas joprojām varēsiet atrast ĆĄo sarunu meklēơanā.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Pamest grupu", @@ -1438,6 +1526,14 @@ "messageformat": "Ć eit ir apvienota abu sarunu ziƆu vēsture.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} ir kontakta {conversationTitle} tālruƆa numurs. JĆ«s abi esat grupas {sharedGroup} dalÄ«bnieki.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} ir kontakta {conversationTitle} tālruƆa numurs", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Attēla sÄ«ktēls no citētās ziƆas", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ZvanÄ«t vēlreiz", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Sākt zvanu", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Pievienoties zvanam/sarunai", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofons izslēgts zvana dalÄ«bnieku skaita dēČ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "PaziƆojumi zvanu laikā", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Zvana/sarunas dalÄ«bnieku limits izsmelts", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Pievienoties", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Sākt", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Zvanā nav vietu", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera atspējota", @@ -1621,10 +1725,6 @@ "messageformat": "Ieslēgt kameru", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Izslēgt", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofons atspējots", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ieslēgt mikrofonu", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "KopÄ«got", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Prezentēơana atspējota", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Pārtraukt prezentēơanu", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ZvanÄ«t", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupa ir pārāk liela, lai zvanÄ«tu dalÄ«bniekiem", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Ieslēgt zvana signālu", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Izslēgt zvana signālu", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Ieslēgt zvana signālu", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Papildu iespējas", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "JĆ«s", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "JĆ«su kamera ir izslēgta", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "SkatÄ«t droĆĄÄ«bas numuru", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ZiƆa", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "SkatÄ«t droĆĄÄ«bas numuru", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Neizdevās ielādēt tālruƆa numuru. Pārbaudiet savienojumu un mēģiniet vēlreiz.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Labojumi var tikt piemēroti tikai 3 stundu laikā pēc ĆĄÄ«s ziƆas nosĆ«tīƥanas.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Labojumus var veikt tikai 24 stundu laikā pēc ĆĄÄ«s ziƆas nosĆ«tīƥanas.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ZiƆojums ir izdzēsts.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Pielikums ir pārāk liels, lai to attēlotu.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "DaĆŸi pielikumi ir pārāk lieli, lai tos attēlotu.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nevar iegĆ«t informāciju par ziedojumu", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Tikai Signal beta versijai", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ZiƆu rediģēơana ir pieejama tikai Signal beta versijas lietotājiem. Ja rediģēsiet ziƆu, tā bĆ«s redzama tikai personām, kuras izmanto Signal beta versiju.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Rediģēt ziƆu", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Ja rediģēsiet ziƆu, tā bĆ«s redzama tikai personām, kuras izmanto jaunākās Signal versijas. Ć Ä«s personas redzēs, ka ziƆa ir rediģēta.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "IenākoĆĄs videozvans
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "IzejoĆĄs balss zvans", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "IzejoĆĄs videozvans", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "Jums zvana {ringer}", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Veido savienojumu vēlreiz
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, zero {{count,number} personu} one {{count,number} persona} other {{count,number} personas}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audiozvans", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Beigt", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Pamest", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofons izslēgts", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofons ieslēgts", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zvana signāls ieslēgts", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zvana signāls izslēgts", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "IestatÄ«jumi", @@ -3468,13 +3668,25 @@ "messageformat": "Zvans pilnekrāna reĆŸÄ«mā", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Pārslēgt uz reĆŸÄŁa skatu", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "MainÄ«t skatu", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Pārslēgt uz skaÄŒruƆa skatu", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ReĆŸÄŁa skats", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Sānjoslas skats", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Runātāja skats", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Skats atjaunināts", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Pamest sarunu", @@ -3576,6 +3788,14 @@ "messageformat": "Labi", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ZiƆu nevar rediģēt", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Ć o ziƆu var rediģēt tikai {max,number} reizes.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Atvainojamies, ka saite sgnl:// bija bezjēdzÄ«ga!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Lietotājvārds", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Radās problēma ar jĆ«su lietotāja vārdu. Tas vairs nav piesaistÄ«ts jĆ«su kontam.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Dzēst lietotājvārdu", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Izveidot lietotājvārdu", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kods vai saite", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Lietotāja vārds ir jāatiestata", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Lietotāja vārda saite ir jāatiestata", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "KopÄ«gojiet savu lietotājvārdu", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Dzēst lietotājvārdu", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Ar ĆĄo darbÄ«bu tiks noƆemts jĆ«su lietotājvārds, un to varēs izmantot citi lietotāji. Vai esat pārliecināts(-a)?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Tādējādi tiks dzēsts jĆ«su lietotājvārds un atslēgts QR kods un saite. “{username}” bĆ«s pieejams citiem lietotājiem. Vai tieƥām to vēlaties?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "JĆ«s nevarēsiet kopÄ«got vai skatÄ«t stāstus. Tiks dzēsti arÄ« jĆ«su nesen veiktie ar stāstu saistÄ«tie ieraksti.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Valoda", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Valoda", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistēmas valoda", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Meklējiet valodas", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Meklējot “{searchTerm}\", rezultātu nav", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "IestatÄ«t", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Restartējiet Signal, lai piemērotu izmaiƆas", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Lai mainÄ«tu valodu, lietotne ir jārestartē.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Restartēt", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Pieejams atjauninājums uz versiju {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "IestatÄ«jumu saglabāƥanas laikā radās kÄŒĆ«da. LĆ«dzu, mēģiniet vēlreiz.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ZiƆa", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Citi stili", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "AtstatÄ«t", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "DarÄ«ts", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Lietotājvārda saites krāsa, {index,number}. no {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Ja atiestatÄ«siet savu QR kodu, esoĆĄais QR kods un saite vairs nedarbosies.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Notiek saites atiestatīƥana
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kods un saite nav iestatÄ«ta. Pārbaudiet tÄ«kla savienojumu un mēģiniet vēlreiz.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Izveidojiet savu Signal lietotāja vārdu", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "rediģēta", + "messageformat": "Rediģēta", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "SĆ«tÄ«t vēlreiz", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Citas darbÄ«bas", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Zvani", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Jauns zvans", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Jauns zvans", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Citas darbÄ«bas", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Dzēst zvanu vēsturi", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Dzēst zvanu vēsturi?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Tiks neatgriezeniski dzēsta visa zvanu vēsture", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "NotÄ«rÄ«t", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Zvanu vēsture izdzēsta", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "NoklikĆĄÄ·iniet, lai skatÄ«tu vai sāktu zvanu", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Meklēt", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrēt pēc neatbildētajiem", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Pārslēgt", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nav neseno zvanu. Sāciet ar zvanu draugam.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Vaicājumam “{query}” nav rezultātu", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "IenākoĆĄs", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "IzejoĆĄs", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Neatbildēts", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Grupas zvans", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nav neseno sarunu.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Vaicājumam “{query}” nav rezultātu", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {IzejoĆĄs balss zvans} other {IenākoĆĄs balss zvans}}} Video {{direction, select, Outgoing {IzejoĆĄs videozvans} other {IenākoĆĄs videozvans}}} Group {{direction, select, Outgoing {IzejoĆĄais grupas zvans} other {IenākoĆĄais grupas zvans}}} other {{direction, select, Outgoing {IzejoĆĄais zvans} other {IenākoĆĄs zvans}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Neatbildēts balss zvans} Video {Neatbildēts videozvans} Group {Neatbildēts grupas zvans} other {Neatbildēts zvans}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Neatbildēts balss zvans} Video {Neatbildēts videozvans} Group {Neatbildēts grupas zvans} other {Neatbildēts zvans}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {NoraidÄ«ts balss zvans} Video {NoraidÄ«ts video zvans} Group {NoraidÄ«ts grupas zvans} other {NoraidÄ«ts zvans}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, zero {{count,number} citi raksta.} one {{count,number} cits raksta.} other {{count,number} citi raksta.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Jaunumi", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Nelielas izmaiƆas, kÄŒĆ«du labojumi un darbÄ«bas uzlabojumi. Paldies, ka lietojat Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ć ajā atjauninājumā ir iekÄŒauti daĆŸi balss un video zvanu uzlabojumi, kā arÄ« daĆŸi nelieli dokumentācijas atjauninājumi (paldies, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Tagad varat mainÄ«t atlasÄ«to valodu Signal platformā, nemainot sistēmas iestatÄ«jumus (Signal iestatÄ«jumi > Izskats > Valoda)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Mēs izmainÄ«jām grupu paziƆojumu ikonas." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Mēs novērsām Ä«slaicÄ«gu aizkavi, kas radās, pievienojoties zvana uzgaidīƥanas telpai macOS ierÄ«cēs, tāpēc tagad jums bĆ«s par vienu attaisnojumu mazāk, ja ieradÄ«sieties uz sapulci ar pussekundes nokavēơanos." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Mēs uzlabojām video elementu pāreju animācijas brÄ«ĆŸos, kad lietotāji pievienojas grupas zvaniem vai pamet tos. KolÄ«dz redzat drauga portretu ieslÄ«dam skatā, ir laiks ieslÄ«gt sarunās." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Tagad sarunas galvenē varat noklikĆĄÄ·ināt uz profila attēla vai grupas avatāra, lai ātri piekÄŒĆ«tu sarunas iestatÄ«jumiem vai apskatÄ«tu vēl neredzētos stāstus ĆĄajā sarunā. Paldies, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/mk-MK/messages.json b/_locales/mk-MK/messages.json index 0576ff3edb..184c1af04e 100644 --- a/_locales/mk-MK/messages.json +++ b/_locales/mk-MK/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Đ“Ń€Đ”ŃˆĐșа ŃĐŸ базата ĐœĐ° ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†Đž", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ĐĐ°ŃŃ‚Đ°ĐœĐ° ĐłŃ€Đ”ŃˆĐșа ŃĐŸ базата ĐœĐ° ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†Đž. ĐœĐŸĐ¶Đ”Ń‚Đ” Ўа ја ĐșĐŸĐżĐžŃ€Đ°Ń‚Đ” ĐłŃ€Đ”ŃˆĐșата Đž Ўа ĐłĐŸ ĐșĐŸĐœŃ‚Đ°ĐșтОратД Ń‚ĐžĐŒĐŸŃ‚ за ĐżĐŸĐŽĐŽŃ€ŃˆĐșа ĐœĐ° Signal за Ўа ĐČĐž ĐżĐŸĐŒĐŸĐłĐœĐ” ĐČĐŸ Ń€Đ”ŃˆĐ°ĐČањД ĐœĐ° ĐżŃ€ĐŸĐ±Đ»Đ”ĐŒĐŸŃ‚. АĐșĐŸ саĐșатД ĐČĐ”ĐŽĐœĐ°Ńˆ Ўа ĐșĐŸŃ€ĐžŃŃ‚ĐžŃ‚Đ” Signal, ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа гО ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ĐČĐ°ŃˆĐžŃ‚Đ” ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†Đž Đž Ўа рДстартОратД.\n\nĐšĐŸĐœŃ‚Đ°ĐșŃ‚ĐžŃ€Đ°Ń˜Ń‚Đ” ĐłĐŸ Ń‚ĐžĐŒĐŸŃ‚ за ĐżĐŸĐŽĐŽŃ€ŃˆĐșа прДĐșу: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž гО сОтД ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†Đž Đž Ń€Đ”ŃŃ‚Đ°Ń€Ń‚ĐžŃ€Đ°Ń˜", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž гО ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†ĐžŃ‚Đ” Đž Ń€Đ”ŃŃ‚Đ°Ń€Ń‚ĐžŃ€Đ°Ń˜", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ХаĐșатД Ń‚Ń€Đ°Ń˜ĐœĐŸ Ўа сД ĐžĐ·Đ±Ń€ĐžŃˆĐ°Ń‚ сОтД ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†Đž?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ЊДлата ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Đ° ĐœĐ° ĐČашО Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž Đž ĐŒĐ”ĐŽĐžŃƒĐŒŃĐșĐž ĐŽĐ°Ń‚ĐŸŃ‚Đ”ĐșĐž ŃœĐ” бОЎат Ń‚Ń€Đ°Ń˜ĐœĐŸ ĐžĐ·Đ±Ń€ĐžŃˆĐ°ĐœĐž ĐŸĐŽ ĐŸĐČĐŸŃ˜ ŃƒŃ€Đ”ĐŽ. ĐŒĐ” ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐșĐŸŃ€ĐžŃŃ‚ĐžŃ‚Đ” Signal ĐœĐ° ĐŸĐČĐŸŃ˜ ŃƒŃ€Đ”ĐŽ ĐŸŃ‚ĐșаĐșĐŸ ĐŸĐŽĐœĐŸĐČĐŸ ŃœĐ” ĐłĐŸ ĐżĐŸĐČрзДтД. ОĐČа ĐœĐ”ĐŒĐ° Ўа гО ĐžĐ·Đ±Ń€ĐžŃˆĐ” ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†ĐžŃ‚Đ” ĐœĐ° ĐČĐ°ŃˆĐžĐŸŃ‚ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœ.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Đ’Đ”Ń€Đ·ĐžŃ˜Đ°Ń‚Đ° ĐŸĐŽ ĐČашата база ĐœĐ° ĐżĐŸĐŽĐ°Ń‚ĐŸŃ†Đž ĐœĐ” сД ŃĐŸĐČпаѓа ŃĐŸ ĐŸĐČаа ĐČĐ”Ń€Đ·ĐžŃ˜Đ° ĐœĐ° Signal. ĐŸŃ€ĐŸĐČДрДтД ЎалО ја ĐŸŃ‚ĐČĐŸŃ€Đ°Ń‚Đ” ĐœĐ°Ń˜ĐœĐŸĐČата ĐČĐ”Ń€Đ·ĐžŃ˜Đ° ĐœĐ° Signal ĐœĐ° ĐČĐ°ŃˆĐžĐŸŃ‚ ĐșĐŸĐŒĐżŃ˜ŃƒŃ‚Đ”Ń€.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Đ”Đ°Ń‚ĐŸŃ‚Đ”Đșа", @@ -300,6 +316,70 @@ "messageformat": "Đ Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ĐĐ”ŃˆŃ‚ĐŸ ĐœĐ” Đ” ĐČĐŸ рДЎ ŃĐŸ ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”, ĐżĐŸĐČĐ”ŃœĐ” ĐœĐ” Đ” ĐœĐ°Đ·ĐœĐ°Ń‡Đ”ĐœĐŸ ĐœĐ° ĐČашата ŃĐŒĐ”Ń‚Đșа. ĐœĐŸĐ¶Đ”Ń‚Đ” Ўа сД ĐŸĐ±ĐžĐŽĐ”Ń‚Đ” Ўа ĐłĐŸ ĐżĐŸŃŃ‚Đ°ĐČОтД ĐŸĐŽĐœĐŸĐČĐŸ ОлО Ўа ОзбДрДтД ĐœĐŸĐČĐŸ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ĐŸĐŸĐżŃ€Đ°ĐČĐž сДга", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ĐĐ”ŃˆŃ‚ĐŸ ĐœĐ” Đ” ĐČĐŸ рДЎ ŃĐŸ Đ»ĐžĐœĐșĐŸŃ‚ за ĐČĐ°ŃˆĐžŃ‚Đ” QR ĐșĐŸĐŽ Đž ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”, ĐżĐŸĐČĐ”ŃœĐ” ĐœĐ” сД ĐČажДчĐșĐž. ĐĄĐŸĐ·ĐŽĐ°Ń˜Ń‚Đ” ĐœĐŸĐČ Đ»ĐžĐœĐș за ŃĐżĐŸĐŽĐ”Đ»ŃƒĐČањД.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ĐŸĐŸĐżŃ€Đ°ĐČĐž сДга", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ПроĐșажО ĐșарточĐșĐž", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ĐĄĐșрој гО ĐșарточĐșОтД", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ĐĐ°ŃŃ‚Đ°ĐœĐ° ĐłŃ€Đ”ŃˆĐșа", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐž", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ĐžĐ·ĐœĐ°Ń‡Đ”ĐœĐŸ ĐșаĐșĐŸ ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐŸ", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Đ Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ĐŸĐŸĐČоцо", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ПроĐșĐ°Đ·ĐœĐž", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐŸĐŸŃŃ‚Đ°ĐČуĐČања", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ĐĐ¶ŃƒŃ€ĐžŃ€Đ°Ń˜ ĐłĐŸ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„ĐžĐ»", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ĐĐ°Đ·Đ°ĐŽ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ОĐČОД Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž сД архоĐČĐžŃ€Đ°ĐœĐž Đž ŃœĐ” сД ĐżĐŸŃ˜Đ°ĐČат ĐČĐŸ ŃĐ°ĐœĐŽĐ°Ń‡Đ”Ń‚ĐŸ ŃĐ°ĐŒĐŸ аĐșĐŸ ĐžĐŒĐ° ĐœĐŸĐČĐž ĐżŃ€ĐžŃŃ‚ĐžĐłĐœĐ°Ń‚Đž ĐżĐŸŃ€Đ°ĐșĐž.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ХДпаĐș ĐżĐŸĐČĐžĐșај", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ПроĐșĐ»ŃƒŃ‡Đž сД сДпаĐș", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ĐŸŃ€ĐŸĐŽĐŸĐ»Đ¶Đž ĐżĐŸĐČĐžĐș", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ĐĄĐ” Đ°Đ¶ŃƒŃ€ĐžŃ€Đ° ĐœĐ°Ń‡ĐžĐœĐŸŃ‚ ĐœĐ° ĐșĐŸŃ˜ Ń„ŃƒĐœĐșŃ†ĐžĐŸĐœĐžŃ€Đ°Đ°Ń‚ Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐžŃ‚Đ” Đ±Ń€ĐŸŃ˜ĐșĐž.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Đ”ĐŸĐ·ĐœĐ°Ń˜Ń‚Đ” ĐżĐŸĐČĐ”ŃœĐ”", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐŸŃ€Đ”Ń‚Ń…ĐŸĐŽĐ”Đœ Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ĐĄĐ»Đ”ĐŽĐ”Đœ Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Đ’Đ”Ń€Đ·ĐžŃ˜Đ° ĐœĐ° Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜, {index,number} ĐŸĐŽ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ĐžĐ·ĐœĐ°Ń‡Đž ĐșаĐșĐŸ ĐżŃ€ĐŸĐČĐ”Ń€Đ”ĐœĐŸ", @@ -663,33 +747,41 @@ "messageformat": "ĐžŃ‚ŃŃ‚Ń€Đ°ĐœĐž ĐżŃ€ĐŸĐČДрĐșа", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "За Ўа ја ĐżŃ€ĐŸĐČДрОтД Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃŃ‚Đ° ĐœĐ° Ń†Đ”Đ»ĐŸŃĐœĐŸŃ‚ĐŸ ŃˆĐžŃ„Ń€ĐžŃ€Đ°ŃšĐ” ŃĐŸ {name}, ŃĐżĐŸŃ€Đ”ĐŽĐ”Ń‚Đ” гО Đ±Ń€ĐŸŃ˜ĐșОтД ĐłĐŸŃ€Đ” ŃĐŸ ŃƒŃ€Đ”ĐŽĐŸŃ‚ ĐœĐ° {name}. Đ˜ŃŃ‚ĐŸ таĐșа ĐŒĐŸĐ¶Đ” Ўа ĐłĐŸ сĐșĐ”ĐœĐžŃ€Đ°Đ°Ń‚ ĐČĐ°ŃˆĐžĐŸŃ‚ ĐșĐŸĐŽ ŃĐŸ ĐœĐžĐČĐœĐžĐŸŃ‚ ŃƒŃ€Đ”ĐŽ.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Đ”ĐŸĐ·ĐœĐ°Ń˜Ń‚Đ” ĐżĐŸĐČĐ”ŃœĐ”", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "За Ўа ја ĐżĐŸŃ‚ĐČрЎОтД Ń†Đ”Đ»ĐŸŃĐœĐ°Ń‚Đ° ŃˆĐžŃ„Ń€ĐžŃ€Đ°ĐœĐŸŃŃ‚ ŃĐŸ {name}, ŃĐżĐŸŃ˜Ń‚Đ” ја ĐșарточĐșата ŃĐŸ Đ±ĐŸŃ˜Đ° ĐżĐŸĐłĐŸŃ€Đ” ŃĐŸ ŃƒŃ€Đ”ĐŽĐŸŃ‚ ĐœĐ° {name} Đž ŃĐżĐŸŃ€Đ”ĐŽĐ”Ń‚Đ” гО Đ±Ń€ĐŸŃ˜ĐșОтД. Đ”ĐŸĐșĐŸĐ»Đșу ĐœĐ” сД ŃĐŸĐČпаѓаат, ĐżŃ€ĐŸĐ±Đ°Ń˜Ń‚Đ” ŃĐŸ Юруг пар Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜ĐșĐž. ĐĄĐ°ĐŒĐŸ Đ”ĐŽĐ”Đœ пар трДба Ўа сД ŃĐŸĐČпаѓа.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "За Ўа ја ĐżŃ€ĐŸĐČДрОтД Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃŃ‚Đ° ĐœĐ° Ń†Đ”Đ»ĐŸŃĐœĐŸŃ‚ĐŸ ŃˆĐžŃ„Ń€ĐžŃ€Đ°ŃšĐ” ŃĐŸ {name}, ŃĐżĐŸŃ€Đ”ĐŽĐ”Ń‚Đ” гО Đ±Ń€ĐŸŃ˜ĐșОтД ĐłĐŸŃ€Đ” ŃĐŸ ŃƒŃ€Đ”ĐŽĐŸŃ‚ ĐœĐ° {name}. Đ˜ŃŃ‚ĐŸ таĐșа ĐŒĐŸĐ¶Đ” Ўа ĐłĐŸ сĐșĐ”ĐœĐžŃ€Đ°Đ°Ń‚ ĐČĐ°ŃˆĐžĐŸŃ‚ ĐșĐŸĐŽ ŃĐŸ ĐœĐžĐČĐœĐžĐŸŃ‚ ŃƒŃ€Đ”ĐŽ.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ĐŸŃ€ĐŸĐŒĐ”ĐœĐž ĐœĐ° Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐžŃ‚Đ” Đ±Ń€ĐŸĐ”ĐČĐž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ĐĄĐ” Đ°Đ¶ŃƒŃ€ĐžŃ€Đ° ĐœĐ°Ń‡ĐžĐœĐŸŃ‚ ĐœĐ° ĐșĐŸŃ˜ Ń„ŃƒĐœĐșŃ†ĐžĐŸĐœĐžŃ€Đ°Đ°Ń‚ Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐžŃ‚Đ” Đ±Ń€ĐŸŃ˜ĐșĐž ĐČĐŸ тДĐșĐŸŃ‚ ĐœĐ° ĐżŃ€Đ”ĐŸĐŽĐ”Đœ ĐżĐ”Ń€ĐžĐŸĐŽ за Ўа сД ĐŸĐČĐŸĐ·ĐŒĐŸĐ¶Đ°Ń‚ ĐżŃ€Đ”Ń‚ŃŃ‚ĐŸŃ˜ĐœĐžŃ‚Đ” Ń„ŃƒĐœĐșцоо за проĐČĐ°Ń‚ĐœĐŸŃŃ‚ ĐœĐ° Signal.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "За Ўа гО ĐżĐŸŃ‚ĐČрЎОтД Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐžŃ‚Đ” Đ±Ń€ĐŸĐ”ĐČĐž, ŃĐżĐŸŃ˜Ń‚Đ” ја ĐșарточĐșата ŃĐŸ Đ±ĐŸŃ˜Đ° ŃĐŸ ŃƒŃ€Đ”ĐŽĐŸŃ‚ ĐœĐ° ĐČĐ°ŃˆĐžĐŸŃ‚ ĐșĐŸĐœŃ‚Đ°Đșт. АĐșĐŸ ĐœĐ” сД ŃĐŸĐČпаѓаат, ĐżĐŸĐČлДчДтД Đž ĐŸĐ±ĐžĐŽĐ”Ń‚Đ” сД ŃĐŸ Юруг пар Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜ĐșĐž. ĐĄĐ°ĐŒĐŸ Đ”ĐŽĐ”Đœ пар трДба Ўа сД ŃĐŸĐČпаѓа.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ĐŸĐŸŃ‚Ń€Đ”Đ±ĐœĐ° Во Đ” ĐżĐŸĐŒĐŸŃˆ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Đ’ĐŸ рДЎ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ĐŒĐ” сД ŃĐŸĐ·ĐŽĐ°ĐŽĐ” Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜ за ĐŸĐČаа Đ»ĐžŃ‡ĐœĐŸŃŃ‚ ĐŸŃ‚ĐșаĐșĐŸ ŃœĐ” Ń€Đ°Đ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€Đ°ĐșĐž.", @@ -1267,10 +1359,6 @@ "messageformat": "ĐŸĐŸĐłĐ»Đ”ĐŽĐœĐž сĐșĐŸŃ€Đ”ŃˆĐœĐ° ĐŒĐ”ĐŽĐžŃƒĐŒŃĐșа ĐŽĐ°Ń‚ĐŸŃ‚Đ”Đșа", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "За Ўа ја ĐżŃ€ĐŸĐČДрОтД Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃŃ‚Đ° ĐœĐ° Ń†Đ”Đ»ĐŸŃĐœĐŸŃ‚ĐŸ ŃˆĐžŃ„Ń€ĐžŃ€Đ°ŃšĐ” ŃĐŸ {name}, ŃĐżĐŸŃ€Đ”ĐŽĐ”Ń‚Đ” гО Đ±Ń€ĐŸŃ˜ĐșОтД ĐłĐŸŃ€Đ” ŃĐŸ ŃƒŃ€Đ”ĐŽĐŸŃ‚ ĐœĐ° {name}. Đ˜ŃŃ‚ĐŸ таĐșа ĐŒĐŸĐ¶Đ°Ń‚ Ўа ĐłĐŸ сĐșĐ”ĐœĐžŃ€Đ°Đ°Ń‚ QR ĐșĐŸĐŽĐŸŃ‚ ĐżĐŸĐłĐŸŃ€Đ”.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Хѐ ŃƒŃˆŃ‚Đ” ĐœĐ”ĐŒĐ°Ń‚Đ” Ń€Đ°Đ·ĐŒĐ”ĐœĐ”Ń‚ĐŸ ĐżĐŸŃ€Đ°ĐșĐž ŃĐŸ ĐŸĐČĐŸŃ˜ ĐșĐŸĐœŃ‚Đ°Đșт. Đ’Đ°ŃˆĐžĐŸŃ‚ Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜ за ĐŸĐČĐŸŃ˜ ĐșĐŸĐœŃ‚Đ°Đșт ŃœĐ” ŃŃ‚Đ°ĐœĐ” ĐŽĐŸŃŃ‚Đ°ĐżĐ”Đœ ĐżĐŸ ĐžŃĐżŃ€Đ°ŃœĐ°ŃšĐ”Ń‚ĐŸ ĐœĐ° прĐČата ĐżĐŸŃ€Đ°Đșа." }, @@ -1334,17 +1422,17 @@ "messageformat": "Đ˜ĐœŃ„ĐŸŃ€ĐŒĐ°Ń†ĐžĐž", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž гО ĐżĐŸŃ€Đ°ĐșОтД", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Да сД ĐžĐ·Đ±Ń€ĐžŃˆĐ” Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ĐŸŃ‚?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Да сД ĐžĐ·Đ±Ń€ĐžŃˆĐ°Ń‚ ĐżĐŸŃ€Đ°ĐșОтД?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ОĐČĐŸŃ˜ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ ŃœĐ” бОЎД ĐžĐ·Đ±Ń€ĐžŃˆĐ°Đœ ĐŸĐŽ ĐŸĐČĐŸŃ˜ ŃƒŃ€Đ”ĐŽ.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ĐŸĐŸŃ€Đ°ĐșОтД ĐČĐŸ ĐŸĐČĐŸŃ˜ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ ŃœĐ” бОЎат ĐžĐ·Đ±Ń€ĐžŃˆĐ°ĐœĐž ĐŸĐŽ ĐŸĐČĐŸŃ˜ ŃƒŃ€Đ”ĐŽ. ĐŒĐ” ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐłĐŸ ĐżŃ€ĐŸĐœĐ°Ń˜ĐŽĐ°Ń‚Đ” ĐŸĐČĐŸŃ˜ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ Đž ĐŸŃ‚ĐșаĐșĐŸ ŃœĐ” гО ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ĐżĐŸŃ€Đ°ĐșОтД.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Напушто ја групата", @@ -1438,6 +1526,14 @@ "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃ˜Đ°Ń‚Đ° ĐœĐ° ĐŽĐČата Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đ° Đ” ŃĐżĐŸĐ”ĐœĐ° туĐșа.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} пропаѓа ĐœĐ° {conversationTitle}. И ĐŽĐČајцата стД Ń‡Đ»Đ”ĐœĐŸĐČĐž ĐœĐ° {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} пропаѓа ĐœĐ° {conversationTitle}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ĐœĐ°Đ»Đ° слОĐșочĐșа ĐŸĐŽ слОĐșата ĐŸĐŽ Ń†ĐžŃ‚ĐžŃ€Đ°ĐœĐ°Ń‚Đ° ĐżĐŸŃ€Đ°Đșа", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ЈаĐČĐž сД ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Đ—Đ°ĐżĐŸŃ‡ĐœĐž ĐżĐŸĐČĐžĐș", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ПроĐșĐ»ŃƒŃ‡Đž сД ĐœĐ° ĐżĐŸĐČĐžĐș", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœĐŸŃ‚ Đ” ОсĐșĐ»ŃƒŃ‡Đ”Đœ Đ·Đ°ŃˆŃ‚ĐŸ ĐžĐŒĐ° ĐłĐŸĐ»Đ”ĐŒ Đ±Ń€ĐŸŃ˜ Đ»ŃƒŃ“Đ” ĐœĐ° ĐżĐŸĐČĐžĐșĐŸŃ‚", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ИзĐČĐ”ŃŃ‚ŃƒĐČања за ĐżĐŸĐČоцо", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ĐŸĐŸĐČĐžĐșĐŸŃ‚ Đ” ĐżĐŸĐ»Đœ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ПроĐșĐ»ŃƒŃ‡Đž сД", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Đ—Đ°ĐżĐŸŃ‡ĐœĐž", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ĐŸĐŸĐČĐžĐșĐŸŃ‚ Đ” ĐżĐŸĐ»Đœ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°Ń‚Đ° Đ” ОсĐșĐ»ŃƒŃ‡Đ”ĐœĐ°", @@ -1621,10 +1725,6 @@ "messageformat": "ВĐșĐ»ŃƒŃ‡Đž ĐșĐ°ĐŒĐ”Ń€Đ°", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ИсĐșĐ»ŃƒŃ‡Đž ОзĐČĐ”ŃŃ‚ŃƒĐČања", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœĐŸŃ‚ Đ” ОсĐșĐ»ŃƒŃ‡Đ”Đœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ВĐșĐ»ŃƒŃ‡Đž ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ĐĄĐżĐŸĐŽĐ”Đ»Đž", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ĐŸŃ€Đ”Đ·Đ”ĐœŃ‚ĐžŃ€Đ°ŃšĐ”Ń‚ĐŸ Đ” ĐŸĐœĐ”ĐČĐŸĐ·ĐŒĐŸĐ¶Đ”ĐœĐŸ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ĐŸŃ€Đ”ŃŃ‚Đ°ĐœĐ”Ń‚Đ” ŃĐŸ ĐżŃ€Đ”Đ·Đ”ĐœŃ‚ĐžŃ€Đ°ŃšĐ”", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ЅĐČĐŸĐœĐž", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Групата Đ” ĐżŃ€Đ”ĐłĐŸĐ»Đ”ĐŒĐ° за Ўа сД јаĐČОтД ĐœĐ° ŃƒŃ‡Đ”ŃĐœĐžŃ†ĐžŃ‚Đ”.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ОĐČĐŸĐ·ĐŒĐŸĐ¶Đž ѕĐČĐŸĐœĐ”ŃšĐ”", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ИсĐșĐ»ŃƒŃ‡Đž ѕĐČĐŸĐœĐ”ŃšĐ”", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ВĐșĐ»ŃƒŃ‡Đž ѕĐČĐŸĐœĐ”ŃšĐ”", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ĐŸĐŸĐČĐ”ŃœĐ” ĐŸĐżŃ†ĐžĐž", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ВОД", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Вашата ĐșĐ°ĐŒĐ”Ń€Đ° Đ” ОсĐșĐ»ŃƒŃ‡Đ”ĐœĐ°", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ВоЮо Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Đ˜ŃĐżŃ€Đ°Ń‚Đ”Ń‚Đ” ĐżĐŸŃ€Đ°Đșа", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ВоЮо Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐ”Đœ Đ±Ń€ĐŸŃ˜", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,7 +2351,7 @@ "messageformat": "ĐĐ”ŃƒŃĐżĐ”ŃˆĐœĐŸ ĐżŃ€ĐŸĐœĐ°ĐŸŃ“Đ°ŃšĐ” ĐœĐ° Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃĐșĐž Đ±Ń€ĐŸŃ˜. ĐŸŃ€ĐŸĐČДрДтД ја ĐžĐœŃ‚Đ”Ń€ĐœĐ”Ń‚ ĐČрсĐșата Đž ĐŸĐ±ĐžĐŽĐ”Ń‚Đ” сД ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { + "icu:ToastManager__CannotEditMessage_24": { "messageformat": "ĐœĐŸĐ¶Đ” Ўа сД ĐżŃ€ĐžĐŒĐ”ĐœŃƒĐČаат ĐžĐ·ĐŒĐ”ĐœĐž ŃĐ°ĐŒĐŸ ĐČĐŸ Ń€ĐŸĐș ĐŸĐŽ 3 часа ĐŸŃ‚ĐșаĐșĐŸ ја ĐžĐŒĐ°Ń‚Đ” ĐžŃĐżŃ€Đ°Ń‚Đ”ĐœĐŸ ĐżĐŸŃ€Đ°Đșата.", "description": "Error message when you try to send an edit after message becomes too old" }, @@ -2480,6 +2596,14 @@ "messageformat": "ОĐČаа ĐżĐŸŃ€Đ°Đșа бДшД ĐžĐ·Đ±Ń€ĐžŃˆĐ°ĐœĐ°.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ĐŸŃ€ĐžĐ»ĐŸĐłĐŸŃ‚ Đ” ĐżŃ€Đ”ĐłĐŸĐ»Đ”ĐŒ за Ўа сД проĐșажД.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ДДл ĐŸĐŽ ĐżŃ€ĐžĐ»ĐŸĐ·ĐžŃ‚Đ” сД ĐżŃ€Đ”ĐłĐŸĐ»Đ”ĐŒĐž за Ўа сД проĐșажат.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ĐĐ” Đ” ĐŒĐŸĐ¶ĐœĐŸ Ўа сД ĐŽĐŸĐ±ĐžŃ˜Đ°Ń‚ ЎДталОтД за ĐŽĐŸĐœĐ°Ń†ĐžŃ˜Đ°Ń‚Đ°", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ĐĄĐ°ĐŒĐŸ ĐČĐŸ бДта ĐČĐ”Ń€Đ·ĐžŃ˜Đ°Ń‚Đ° ĐœĐ° Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Đ˜Đ·ĐŒĐ”ĐœŃƒĐČĐ°ŃšĐ”Ń‚ĐŸ ĐżĐŸŃ€Đ°ĐșĐž Đ” ĐŽĐŸŃŃ‚Đ°ĐżĐœĐŸ ŃĐ°ĐŒĐŸ за бДта ĐșĐŸŃ€ĐžŃĐœĐžŃ†ĐžŃ‚Đ” ĐœĐ° Signal. АĐșĐŸ ĐžĐ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€Đ°Đșа, ŃœĐ” бОЎД ĐČОЎлОĐČа ŃĐ°ĐŒĐŸ за лОцата ĐșĐŸĐž ја ĐșĐŸŃ€ĐžŃŃ‚Đ°Ń‚ ĐżĐŸŃĐ»Đ”ĐŽĐœĐ°Ń‚Đ° ĐČĐ”Ń€Đ·ĐžŃ˜Đ° ĐœĐ° Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐž ја ĐżĐŸŃ€Đ°Đșата", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "АĐșĐŸ ĐžĐ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€Đ°Đșа, ŃœĐ” бОЎД ĐČОЎлОĐČа ŃĐ°ĐŒĐŸ за лОцата ĐșĐŸĐž ја ĐșĐŸŃ€ĐžŃŃ‚Đ°Ń‚ ĐżĐŸŃĐ»Đ”ĐŽĐœĐ°Ń‚Đ° ĐČĐ”Ń€Đ·ĐžŃ˜Đ° ĐœĐ° Signal. ĐŒĐ” ĐŒĐŸĐ¶Đ°Ń‚ Ўа ĐČоЮат ĐŽĐ”Đșа ја ĐžĐŒĐ°Ń‚Đ” ĐžĐ·ĐŒĐ”ĐœĐ”Ń‚ĐŸ ĐżĐŸŃ€Đ°Đșата.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Đ”ĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐČĐžĐŽĐ”ĐŸ-ĐżĐŸĐČĐžĐș
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐș", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ĐČĐž сД јаĐČуĐČа", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ĐŸĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ ĐżĐŸĐČŃ€Đ·ŃƒĐČањД ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} Đ»ĐžŃ‡ĐœĐŸŃŃ‚} other {{count,number} Đ»ŃƒŃ“Đ”}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ĐŃƒĐŽĐžĐŸ ĐżĐŸĐČĐžĐș", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Крај", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Напушто", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœĐŸŃ‚ Đ” ОсĐșĐ»ŃƒŃ‡Đ”Đœ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœĐŸŃ‚ Đ” ĐČĐșĐ»ŃƒŃ‡Đ”Đœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ЅĐČĐŸĐœĐ”ŃšĐ”Ń‚ĐŸ Đ” ĐŸĐČĐŸĐ·ĐŒĐŸĐ¶Đ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ЅĐČĐŸĐœĐ”ŃšĐ”Ń‚ĐŸ Đ” ĐŸĐœĐ”ĐČĐŸĐ·ĐŒĐŸĐ¶Đ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐŸĐŸŃŃ‚Đ°ĐČуĐČања", @@ -3468,13 +3668,25 @@ "messageformat": "ĐŸĐŸĐČĐžĐș ĐœĐ° цДл Đ”ĐșŃ€Đ°Đœ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐĄĐŒĐ”ĐœĐž ĐČĐŸ ĐŒŃ€Đ”Đ¶Đ°ŃŃ‚ ĐżĐŸĐłĐ»Đ”ĐŽ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐž ĐłĐŸ ĐżŃ€Đ”ĐłĐ»Đ”ĐŽĐŸŃ‚ ĐœĐ° ŃƒŃ‡Đ”ŃĐœĐžŃ†Đž", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ĐĄĐŒĐ”ĐœĐž ĐČĐŸ ĐżĐŸĐłĐ»Đ”ĐŽ за ŃĐŸĐłĐŸĐČĐŸŃ€ĐœĐžĐș", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽ ĐșаĐșĐŸ ĐŒŃ€Đ”Đ¶Đ°", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽ ŃĐŸ ŃŃ‚Ń€Đ°ĐœĐžŃ‡ĐœĐ° Đ»Đ”ĐœŃ‚Đ°", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽ ĐœĐ° ĐłĐŸĐČĐŸŃ€ĐœĐžĐș", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽĐŸŃ‚ Đ” Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°Đœ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Напушто ĐżĐŸĐČĐžĐș", @@ -3576,6 +3788,14 @@ "messageformat": "Đ’ĐŸ рДЎ", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ĐŸĐŸŃ€Đ°Đșата ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа сД ĐžĐ·ĐŒĐ”ĐœĐž", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ĐœĐŸĐ¶Đ” Ўа сД ĐœĐ°ĐżŃ€Đ°ĐČат ŃĐ°ĐŒĐŸ {max,number} ĐžĐ·ĐŒĐ”ĐœĐž ĐœĐ° ĐŸĐČаа ĐżĐŸŃ€Đ°Đșа.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ИзĐČĐžĐœĐ”Ń‚Đ”, Đ»ĐžĐœĐșĐŸŃ‚ sgnl:// ĐœĐ”ĐŒĐ° ŃĐŒĐžŃĐ»Đ°!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ĐĐ”ŃˆŃ‚ĐŸ ĐœĐ” Đ” ĐČĐŸ рДЎ ŃĐŸ ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”, ĐżĐŸĐČĐ”ŃœĐ” ĐœĐ” Đ” ĐœĐ°Đ·ĐœĐ°Ń‡Đ”ĐœĐŸ ĐœĐ° ĐČашата ŃĐŒĐ”Ń‚Đșа.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ĐłĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸŃ‚ĐŸ ĐžĐŒĐ”", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ĐĄĐŸĐŽĐ°ĐŽĐ”Ń‚Đ” ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ĐșĐŸĐŽ ОлО Đ»ĐžĐœĐș", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸŃ‚ĐŸ ĐžĐŒĐ” трДба Ўа сД рДсДтОра", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Đ›ĐžĐœĐșĐŸŃ‚ за ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸŃ‚ĐŸ ĐžĐŒĐ” трДба Ўа сД рДсДтОра", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ĐĄĐżĐŸĐŽĐ”Đ»Đ”Ń‚Đ” ĐłĐŸ ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ĐłĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸŃ‚ĐŸ ĐžĐŒĐ”", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ĐĄĐŸ ĐŸĐČа ŃœĐ” сД ĐŸŃ‚ŃŃ‚Ń€Đ°ĐœĐž ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”, ĐŸĐČĐŸĐ·ĐŒĐŸĐ¶ŃƒĐČајќо ĐžĐŒ ĐœĐ° Юруго ĐșĐŸŃ€ĐžŃĐœĐžŃ†Đž Ўа ĐłĐŸ ŃƒĐżĐŸŃ‚Ń€Đ”Đ±Đ°Ń‚. ДалО стД ŃĐžĐłŃƒŃ€ĐœĐž?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ОĐČа ŃœĐ” ĐłĐŸ ĐŸŃ‚ŃŃ‚Ń€Đ°ĐœĐž ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ” Đž ŃœĐ” гО ĐŸĐœĐ”ĐČĐŸĐ·ĐŒĐŸĐ¶Đž ĐČĐ°ŃˆĐžŃ‚Đ” QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș. ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸŃ‚ĐŸ ĐžĐŒĐ” „{username}“ ŃœĐ” бОЎД ĐŽĐŸŃŃ‚Đ°ĐżĐœĐŸ за ĐŸŃŃ‚Đ°ĐœĐ°Ń‚ĐžŃ‚Đ” ĐșĐŸŃ€ĐžŃĐœĐžŃ†Đž. ДалО стД ŃĐžĐłŃƒŃ€ĐœĐž?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ĐŸĐŸĐČĐ”ŃœĐ” ĐœĐ”ĐŒĐ° Ўа ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ŃĐżĐŸĐŽĐ”Đ»ŃƒĐČатД ОлО глДЎатД проĐșĐ°Đ·ĐœĐž. ĐĐ”ĐŸĐŽĐ°ĐŒĐœĐ° ŃĐżĐŸĐŽĐ”Đ»Đ”ĐœĐžŃ‚Đ” ĐœĐŸĐČĐŸŃŃ‚Đž ĐœĐ° проĐșĐ°Đ·ĐœĐ°Ń‚Đ° ĐžŃŃ‚ĐŸ таĐșа ŃœĐ” бОЎат ĐžĐ·Đ±Ń€ĐžŃˆĐ°ĐœĐž.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ЈазОĐș", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ЈазОĐș", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ĐĄĐžŃŃ‚Đ”ĐŒŃĐșĐž јазОĐș", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ĐŸŃ€Đ”Đ±Đ°Ń€Đ°Ń˜ Ń˜Đ°Đ·ĐžŃ†Đž", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ĐĐ” сД ĐżŃ€ĐŸĐœĐ°Ń˜ĐŽĐ”ĐœĐž Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đž за „{searchTerm}“", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ĐŸĐŸŃŃ‚Đ°ĐČĐž", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Đ Đ”ŃŃ‚Đ°Ń€Ń‚ĐžŃ€Đ°Ń˜ ĐłĐŸ Signal за Ўа сД ĐżŃ€ĐžĐŒĐ”ĐœĐ°Ń‚ ĐżŃ€ĐŸĐŒĐ”ĐœĐžŃ‚Đ”", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "АплОĐșацојата трДба Ўа сД рДстартОра за Ўа сД ŃĐŒĐ”ĐœĐž јазОĐșĐŸŃ‚.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Đ Đ”ŃŃ‚Đ°Ń€Ń‚ĐžŃ€Đ°Ń˜", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Đ”ĐŸŃŃ‚Đ°ĐżĐœĐŸ Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°ŃšĐ” ĐŽĐŸ ĐČĐ”Ń€Đ·ĐžŃ˜Đ° {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ĐĄĐ” ĐżĐŸŃ˜Đ°ĐČĐž ĐłŃ€Đ”ŃˆĐșа про Đ·Đ°Ń‡ŃƒĐČуĐČањД ĐœĐ° ĐżĐŸŃŃ‚Đ°ĐČуĐČањата. Đ’Đ” ĐŒĐŸĐ»ĐžĐŒĐ” ĐŸĐ±ĐžĐŽĐ”Ń‚Đ” сД ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ĐŸĐŸŃ€Đ°Đșа", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ĐŸĐŸĐČĐ”ŃœĐ” ŃŃ‚ĐžĐ»ĐŸĐČĐž", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "РДсДтОраj", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Đ“ĐŸŃ‚ĐŸĐČĐŸ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Đ‘ĐŸŃ˜Đ° ĐœĐ° Đ»ĐžĐœĐșĐŸŃ‚ ŃĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”, {index,number} ĐŸĐŽ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Đ”ĐŸĐșĐŸĐ»Đșу ĐłĐŸ рДсДтОратД ĐČĐ°ŃˆĐžĐŸŃ‚ QR ĐșĐŸĐŽ, ĐČĐ°ŃˆĐžŃ‚Đ” ĐżĐŸŃŃ‚ĐŸĐ”Ń‡ĐșĐž QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș ĐżĐŸĐČĐ”ŃœĐ” ĐœĐ”ĐŒĐ° Ўа Ń„ŃƒĐœĐșŃ†ĐžĐŸĐœĐžŃ€Đ°Đ°Ń‚.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Đ›ĐžĐœĐșĐŸŃ‚ сД рДсДтОра ", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "ĐĐ” сД ĐżĐŸŃŃ‚Đ°ĐČĐ”ĐœĐž QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș. ĐŸŃ€ĐŸĐČДрДтД ја ĐŒŃ€Đ”Đ¶ĐœĐ°Ń‚Đ° ĐżĐŸĐČŃ€Đ·Đ°ĐœĐŸŃŃ‚ Đž ĐŸĐ±ĐžĐŽĐ”Ń‚Đ” сД ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ĐŸĐŸŃŃ‚Đ°ĐČДтД ĐłĐŸ ĐČĐ°ŃˆĐ”Ń‚ĐŸ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ” ĐœĐ° Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "ĐžĐ·ĐŒĐ”ĐœĐ”Ń‚ĐŸ", + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ”Ń‚ĐŸ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Испрато ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ĐŸĐŸĐČĐ”ŃœĐ” ĐŽĐ”Ń˜ŃŃ‚ĐČОја", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ĐŸĐŸĐČоцо", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ĐĐŸĐČ ĐżĐŸĐČĐžĐș", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ĐĐŸĐČ ĐżĐŸĐČĐžĐș", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ĐŸĐŸĐČĐ”ŃœĐ” ĐŽĐ”Ń˜ŃŃ‚ĐČОја", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ја ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Đ°Ń‚Đ° ĐœĐ° ĐżĐŸĐČоцо", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Да сД ĐžĐ·Đ±Ń€ĐžŃˆĐ” ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Đ°Ń‚Đ° ĐœĐ° ĐżĐŸĐČоцо?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ОĐČа Ń‚Ń€Đ°Ń˜ĐœĐŸ ŃœĐ” ја ĐžĐ·Đ±Ń€ĐžŃˆĐ” ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Đ°Ń‚Đ° ĐœĐ° ĐżĐŸĐČоцо", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Исчосто", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐ°ĐœĐ° Đ” ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Đ°Ń‚Đ° ĐœĐ° ĐżĐŸĐČоцо", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "КлОĐșĐœĐ”Ń‚Đ” за Ўа гО прДглДЎатД ĐżĐŸĐČОцОтД ОлО за Ўа Đ·Đ°ĐżĐŸŃ‡ĐœĐ”Ń‚Đ” ĐœĐŸĐČ ĐżĐŸĐČĐžĐș", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Барај", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Đ€ĐžĐ»Ń‚Ń€ĐžŃ€Đ°Ń˜ гО ĐżŃ€ĐŸĐżŃƒŃˆŃ‚Đ”ĐœĐžŃ‚Đ” ĐżĐŸĐČоцо", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ĐĄĐŒĐ”ĐœĐž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĐĐ”ĐŒĐ° сĐșĐŸŃ€Đ”ŃˆĐœĐž ĐżĐŸĐČоцо. Đ—Đ°ĐżĐŸŃ‡ĐœĐ”Ń‚Đ” ŃĐŸ јаĐČуĐČањД ĐœĐ° ĐżŃ€ĐžŃ˜Đ°Ń‚Đ”Đ».", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ĐĐ” сД ĐżŃ€ĐŸĐœĐ°Ń˜ĐŽĐ”ĐœĐž Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đž за „{query}“", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Đ”ĐŸŃ˜ĐŽĐŸĐČĐ”Đœ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Đ“Ń€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĐĐ”ĐŒĐ° ĐœĐ”ĐŸĐŽĐ°ĐŒĐœĐ”ŃˆĐœĐž Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€Đž.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ĐĐ” сД ĐżŃ€ĐŸĐœĐ°Ń˜ĐŽĐ”ĐœĐž Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đž за „{query}“", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș} other {Đ”ĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș}}} Video {{direction, select, Outgoing {ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐș} other {Đ”ĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐș}}} Group {{direction, select, Outgoing {ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐłŃ€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș} other {Đ”ĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐłŃ€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș}}} other {{direction, select, Outgoing {ĐŸĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș} other {Đ”ĐŸŃ˜ĐŽĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș} Video {Đ˜ŃĐżŃƒŃˆŃ‚Đ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐș} Group {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐłŃ€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș} other {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐżĐŸĐČĐžĐș}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ĐĐ”ĐŸĐŽĐłĐŸĐČĐŸŃ€Đ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș} Video {ĐĐ”ĐŸĐŽĐŸĐłĐŸĐČĐŸŃ€Đ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐș} Group {ĐĐ”ĐŸĐŽĐłĐŸĐČĐŸŃ€Đ”Đœ ĐłŃ€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș} other {ĐĐ”ĐŸĐŽĐłĐŸĐČĐŸŃ€Đ”Đœ ĐżĐŸĐČĐžĐș}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ĐžĐŽĐ±ĐžĐ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐ”Đœ ĐżĐŸĐČĐžĐș} Video {ĐžĐŽĐ±ĐžĐ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČĐžĐș} Group {ĐžĐŽĐ±ĐžĐ”Đœ ĐłŃ€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș} other {ĐžĐŽĐ±ĐžĐ”Đœ ĐżĐŸĐČĐžĐș}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {ĐŁŃˆŃ‚Đ” {count,number} лОцД пОшуĐČа.} other {ĐŁŃˆŃ‚Đ” {count,number} лОца пОшуĐČаат.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ĐšŃ‚ĐŸ Đ” ĐœĐŸĐČĐŸ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "MалО ĐżĐŸĐŽĐŸĐ±Ń€ŃƒĐČања, Ń€Đ”ŃˆĐ”ĐœĐž Đ±Đ°ĐłĐŸĐČĐž Đž ĐżĐŸĐŽĐŸĐ±Ń€ŃƒĐČања ĐœĐ° ĐżĐ”Ń€Ń„ĐŸŃ€ĐŒĐ°ĐœŃĐŸŃ‚. Во Đ±Đ»Đ°ĐłĐŸĐŽĐ°Ń€ĐžĐŒĐ” ŃˆŃ‚ĐŸ ĐșĐŸŃ€ĐžŃŃ‚ĐžŃ‚Đ” Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ОĐČаа ĐČĐ”Ń€Đ·ĐžŃ˜Đ° ĐČĐșĐ»ŃƒŃ‡ŃƒĐČа ĐœĐ”ĐșĐŸĐ»Đșу ĐżĐŸĐŽĐŸĐ±Ń€ŃƒĐČања за ĐłĐ»Đ°ŃĐŸĐČĐœĐž Đž ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐČоцо, а Đž ĐœĐ”ĐșĐŸĐž ĐŒĐ°Đ»Đž Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°ŃšĐ° ĐœĐ° ĐŽĐŸĐșŃƒĐŒĐ”ĐœŃ‚Đ°Ń†ĐžŃ˜Đ°Ń‚Đ° (Đ±Đ»Đ°ĐłĐŸĐŽĐ°Ń€ĐžĐŒĐ”, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "ХДга ĐŒĐŸĐ¶Đ” Ўа сД ŃĐŒĐ”ĐœĐž ĐžĐ·Đ±Ń€Đ°ĐœĐžĐŸŃ‚ јазОĐș ĐČĐŸ Signal бДз Ўа сД ĐŒĐ”ĐœŃƒĐČаат ŃĐžŃŃ‚Đ”ĐŒŃĐșОтД ĐżĐŸŃŃ‚Đ°ĐČуĐČања (ĐŸĐŸŃŃ‚Đ°ĐČуĐČања ĐœĐ° Signal > ИзглДЎ > ЈазОĐș)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Го ĐŸĐ±ĐœĐŸĐČĐžĐČĐŒĐ” ĐžĐșĐŸĐœĐžŃ‚Đ” за ОзĐČĐ”ŃŃ‚ŃƒĐČања ĐČĐŸ групо." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Đ“ĐŸ ĐżĐŸĐżŃ€Đ°ĐČĐžĐČĐŒĐ” ĐșратĐșĐŸŃ‚ĐŸ ĐŽĐŸŃ†ĐœĐ”ŃšĐ” ŃˆŃ‚ĐŸ ĐœĐ”ĐșĐŸĐłĐ°Ńˆ сД ŃĐ»ŃƒŃ‡ŃƒĐČашД ĐœĐ° macOS ĐżĐŸ ĐČĐșĐ»ŃƒŃ‡ŃƒĐČањД ĐœĐ° ĐżĐŸĐČĐžĐș." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Ја ĐżĐŸĐżŃ€Đ°ĐČĐžĐČĐŒĐ” ĐżŃ€Đ”ĐŸĐŽĐœĐ°Ń‚Đ° Đ°ĐœĐžĐŒĐ°Ń†ĐžŃ˜Đ° за ĐČĐžĐŽĐ”ĐŸ ĐżĐ»ĐŸŃ‡ĐșОтД ĐșĐŸĐłĐ° ĐœĐ”ĐșĐŸŃ˜ сД ĐżŃ€ĐžĐŽŃ€ŃƒĐ¶ŃƒĐČа ОлО ĐœĐ°ĐżŃƒŃˆŃ‚Đ° ĐłŃ€ŃƒĐżĐ”Đœ ĐżĐŸĐČĐžĐș." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ХДга ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐșлОĐșĐœĐ”Ń‚Đ” ĐœĐ° ĐżŃ€ĐŸŃ„ĐžĐ»ĐœĐ° слОĐșа ОлО аĐČатар ĐœĐ° група ĐČĐŸ заглаĐČĐžĐ”Ń‚ĐŸ ĐœĐ° Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ĐŸŃ‚ за брз простап ĐŽĐŸ ĐżĐŸŃŃ‚Đ°ĐČуĐČањата ĐœĐ° Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ĐŸŃ‚ ОлО за Ўа гО ĐČОЎОтД ĐœĐ”ĐŸŃ‚ĐČĐŸŃ€Đ”ĐœĐžŃ‚Đ” проĐșĐ°Đ·ĐœĐž ĐŸĐŽ Ń‚ĐŸŃ˜ Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€. Đ‘Đ»Đ°ĐłĐŸĐŽĐ°Ń€ĐžĐŒĐ”, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ml-IN/messages.json b/_locales/ml-IN/messages.json index 1a8919554c..6ce25a0293 100644 --- a/_locales/ml-IN/messages.json +++ b/_locales/ml-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àŽĄàŽŸàŽ±à”àŽ±àŽŸàŽŹà”‡àŽžà” àŽȘàŽżàŽ¶àŽ•à”", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àŽĄàŽŸàŽ±à”àŽ±àŽŸàŽŹà”‡àŽžà” àŽȘàŽżàŽ¶àŽ•à”àŽŁà”àŽŸàŽŸàŽŻàŽż. àŽȘàŽżàŽ¶àŽ•à” àŽȘàŽ•à”ŒàŽ€à”àŽ€àŽżàŽŻàŽ€àŽżàŽšà” àŽ¶à”‡àŽ·àŽ‚ Signal àŽȘàŽżàŽšà”àŽ€à”àŽŁàŽŻà”àŽźàŽŸàŽŻàŽż àŽŹàŽšà”àŽ§àŽȘà”àŽȘà”†àŽŸà”àŽŸà” àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•à” àŽȘà”àŽ°àŽ¶à”â€ŒàŽšàŽ‚ àŽȘàŽ°àŽżàŽčàŽ°àŽżàŽ•à”àŽ•àŽŸàŽ‚. àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•à” Signal àŽ‡àŽȘà”àŽȘà”‹à”Ÿ àŽ€àŽšà”àŽšà”† àŽ‰àŽȘàŽŻà”‹àŽ—àŽżàŽ•à”àŽ•àŽŁàŽźà”†àŽ™à”àŽ•àŽżà”œ, àŽĄàŽŸàŽ±à”àŽ± àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽż àŽȘà”àŽšàŽ°àŽŸàŽ°àŽ‚àŽ­àŽżàŽ•à”àŽ•àŽŸàŽ‚.\n\nàŽˆ àŽČàŽżàŽ™à”àŽ•à” àŽžàŽšà”àŽŠà”ŒàŽ¶àŽżàŽšà”àŽšà” àŽȘàŽżàŽšà”àŽ€à”àŽŁàŽŻà”àŽźàŽŸàŽŻàŽż àŽŹàŽšà”àŽ§àŽȘà”àŽȘà”†àŽŸà”àŽ•: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àŽŽàŽČà”àŽČàŽŸ àŽĄàŽŸàŽ±à”àŽ±àŽŻà”àŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽż àŽȘà”àŽšàŽ°àŽŸàŽ°àŽ‚àŽ­àŽżàŽ•à”àŽ•à”àŽ•", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àŽĄàŽŸàŽ±à”àŽ±àŽŸ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽż àŽȘà”àŽšàŽ°àŽŸàŽ°àŽ‚àŽ­àŽżàŽ•à”àŽ•à”àŽ•", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àŽŽàŽČà”àŽČàŽŸ àŽĄàŽŸàŽ±à”àŽ±àŽŻà”àŽ‚ àŽ¶àŽŸàŽ¶à”àŽ”àŽ€àŽźàŽŸàŽŻàŽż àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽŁà”‹?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽŽàŽČà”àŽČàŽŸ àŽžàŽšà”àŽŠà”‡àŽ¶ àŽšàŽ°àŽżàŽ€à”àŽ°àŽ”à”àŽ‚ àŽźà”€àŽĄàŽżàŽŻàŽŻà”àŽ‚ àŽˆ àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ€à”àŽ€àŽżà”œ àŽšàŽżàŽšà”àŽšà” àŽ¶àŽŸàŽ¶à”àŽ”àŽ€àŽźàŽŸàŽŻàŽż àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”àŽ‚. Signal àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽČàŽżàŽ™à”àŽ•à” àŽšà”†àŽŻà”â€ŒàŽ€ àŽ¶à”‡àŽ·àŽ‚ àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•à” àŽˆ àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ€à”àŽ€àŽżà”œ Signal àŽ‰àŽȘàŽŻà”‹àŽ—àŽżàŽ•à”àŽ•àŽŸàŽšàŽŸàŽ•à”àŽ‚. àŽ‡àŽ€à” àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ«à”‹àŽŁàŽżà”œ àŽšàŽżàŽšà”àŽšà” àŽĄàŽŸàŽ±à”àŽ±àŽŻà”†àŽŸàŽšà”àŽšà”àŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽżàŽČà”àŽČ.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽĄàŽŸàŽ±à”àŽ±àŽŸàŽŹà”‡àŽžàŽżàŽšà”àŽ±à”† àŽȘàŽ€àŽżàŽȘà”àŽȘà” àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† Signal àŽȘàŽ€àŽżàŽȘà”àŽȘà”àŽźàŽŸàŽŻàŽż àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽšà”àŽšàŽżàŽČà”àŽČ. àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•àŽźà”àŽȘà”àŽŻà”‚àŽŸà”àŽŸàŽ±àŽżà”œ Signal-àŽšà”àŽ±à”† àŽàŽ±à”àŽ±àŽ”à”àŽ‚ àŽȘà”àŽ€àŽżàŽŻ àŽȘàŽ€àŽżàŽȘà”àŽȘàŽŸàŽŁà” àŽ€à”àŽ±àŽ•à”àŽ•à”àŽšà”àŽšàŽ€à”†àŽšà”àŽšà” àŽ‰àŽ±àŽȘà”àŽȘàŽŸàŽ•à”àŽ•à”àŽ•.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&àŽ«àŽŻà”œ", @@ -300,6 +316,70 @@ "messageformat": "àŽšàŽŸàŽ±à”àŽ±à”àŽ•à”Ÿ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ”à”àŽźàŽŸàŽŻàŽż àŽŹàŽšà”àŽ§àŽȘà”àŽȘà”†àŽŸà”àŽŸà” àŽŽàŽšà”àŽ€à”‹ àŽȘàŽżàŽ¶àŽ•à”àŽŁà”àŽŸàŽŸàŽŻàŽż, àŽ‡àŽ€à” àŽšàŽżàŽČàŽ”àŽżà”œ àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ…àŽ•à”àŽ•à”—àŽŁà”àŽŸàŽżàŽČà”‡àŽ•à”àŽ•à” àŽ…àŽžà”ˆà”» àŽšà”†àŽŻà”àŽ€àŽżàŽŸà”àŽŸàŽżàŽČà”àŽČ. àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•àŽ€à” àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽžàŽœà”àŽœàŽźàŽŸàŽ•à”àŽ•àŽŸà”» àŽ¶à”àŽ°àŽźàŽżàŽ•à”àŽ•àŽŸàŽ‚ àŽ…àŽČà”àŽČà”†àŽ™à”àŽ•àŽżà”œ àŽȘà”àŽ€àŽżàŽŻà”†àŽŸàŽ°à”†àŽŁà”àŽŁàŽ‚ àŽ€àŽżàŽ°àŽžà”àŽžà”†àŽŸà”àŽ•à”àŽ•àŽŸàŽ‚.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àŽ‡àŽȘà”àŽȘà”‹à”Ÿ àŽȘàŽ°àŽżàŽčàŽ°àŽżàŽ•à”àŽ•à”àŽ•", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† QR àŽ•à”‹àŽĄà”àŽ‚ àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽź àŽČàŽżàŽ™à”àŽ•à”àŽźàŽŸàŽŻà”àŽ‚ àŽŹàŽšà”àŽ§àŽȘà”àŽȘà”†àŽŸà”àŽŸà” àŽŽàŽšà”àŽ€à”‹ àŽ•à”àŽŽàŽȘà”àŽȘàŽ‚ àŽžàŽ‚àŽ­àŽ”àŽżàŽšà”àŽšà”, àŽ‡àŽ€àŽżàŽšà” àŽ‡àŽšàŽż àŽžàŽŸàŽ§à”àŽ€àŽŻàŽżàŽČà”àŽČ. àŽźàŽ±à”àŽ±à”àŽłà”àŽłàŽ”àŽ°à”àŽźàŽŸàŽŻàŽż àŽȘàŽ™à”àŽ•àŽżàŽŸàŽŸà”» àŽȘà”àŽ€àŽżàŽŻà”ŠàŽ°à” àŽČàŽżàŽ™à”àŽ•à” àŽžà”ƒàŽ·à”â€ŒàŽŸàŽżàŽ•à”àŽ•à”àŽ•.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àŽ‡àŽȘà”àŽȘà”‹à”Ÿ àŽȘàŽ°àŽżàŽčàŽ°àŽżàŽ•à”àŽ•à”àŽ•", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àŽŸàŽŸàŽŹà”àŽ•à”Ÿ àŽ•àŽŸàŽŁàŽżàŽ•à”àŽ•à”àŽ•", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àŽŸàŽŸàŽŹà”àŽ•à”Ÿ àŽźàŽ±àŽŻà”àŽ•à”àŽ•à”àŽ•", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àŽ’àŽ°à” àŽȘàŽżàŽ¶àŽ•à”àŽŁà”àŽŸàŽŸàŽŻàŽż", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "àŽ”àŽŸàŽŻàŽżàŽ•à”àŽ•àŽŸàŽ€à”àŽ€ {count,number} àŽŽàŽŁà”àŽŁàŽ‚", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àŽ”àŽŸàŽŻàŽżàŽšà”àŽšàŽżàŽŸà”àŽŸàŽżàŽČà”àŽČàŽŸàŽ€à”àŽ€àŽ€àŽŸàŽŻàŽż àŽ…àŽŸàŽŻàŽŸàŽłàŽȘà”àŽȘà”†àŽŸà”àŽ€à”àŽ€àŽż", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àŽšàŽŸàŽ±à”àŽ±à”àŽ•à”Ÿ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àŽ•à”‹àŽłà”àŽ•à”Ÿ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àŽžà”àŽ±à”àŽ±à”‹àŽ±àŽżàŽ•à”Ÿ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽŁàŽ™à”àŽ™à”Ÿ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”àŽ•", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àŽȘà”àŽ°à”†àŽŸàŽ«à”ˆà”œ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àŽ€àŽżàŽ°àŽżàŽ•à”† àŽȘà”‹àŽ•à”àŽ•", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àŽˆ àŽšàŽŸàŽ±à”àŽ±à”àŽ•à”Ÿ àŽ†à”ŒàŽ•à”àŽ•à”ˆàŽ”à” àŽšà”†àŽŻà”àŽ€àŽżàŽŸà”àŽŸà”àŽŁà”àŽŸà”, àŽȘà”àŽ€àŽżàŽŻ àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽ”àŽšà”àŽšàŽŸà”œ àŽźàŽŸàŽ€à”àŽ°àŽźà”‡ àŽ…àŽ” àŽ‡à”»àŽŹà”‹àŽ•à”àŽžàŽżà”œ àŽŠà”ƒàŽ¶à”àŽŻàŽźàŽŸàŽ•à”‚.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àŽŽàŽšà”àŽ€àŽŸàŽŻàŽŸàŽČà”àŽ‚ àŽ”àŽżàŽłàŽżàŽ•à”àŽ•à”àŽ•", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àŽŽàŽ™à”àŽ™àŽšà”†àŽŻàŽŸàŽŻàŽŸàŽČà”àŽ‚ àŽšà”‡àŽ°à”àŽ•", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àŽ•à”‹à”Ÿ àŽ€à”àŽŸàŽ°à”àŽ•", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘàŽ±à”àŽ•à”Ÿ àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”àŽ•àŽŻàŽŸàŽŁà”.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àŽ•à”‚àŽŸà”àŽ€à”œ àŽ…àŽ±àŽżàŽŻà”àŽ•", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àŽźà”àŽźà”àŽȘàŽ€à”àŽ€à”† àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àŽ…àŽŸà”àŽ€à”àŽ€ àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ àŽȘàŽ€àŽżàŽȘà”àŽȘà”, {total,number}-à”œ {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽšàŽ€àŽŸàŽŻàŽż àŽ…àŽŸàŽŻàŽŸàŽłàŽȘà”àŽȘà”†àŽŸà”àŽ€à”àŽ€à”àŽ•", @@ -663,33 +747,41 @@ "messageformat": "àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽš àŽȘà”‚à”ŒàŽ€à”àŽ€àŽżàŽŻàŽŸàŽ•à”àŽ•à”àŽ•", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} àŽŽàŽšà”àŽšàŽŻàŽŸàŽłà”àŽźàŽŸàŽŻàŽż àŽ†àŽŠà”àŽŻàŽ”àŽžàŽŸàŽšàŽ‚ àŽŽà”»àŽ•à”àŽ°àŽżàŽȘà”àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”œ àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽšà”àŽ±àŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”» àŽ…àŽ”àŽ°à”àŽŸà”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ”à”àŽźàŽŸàŽŻàŽż àŽźà”àŽ•àŽłàŽżàŽČà”àŽłà”àŽł àŽ…àŽ•à”àŽ•àŽ™à”àŽ™à”Ÿ àŽ€àŽŸàŽ°àŽ€àŽźà”àŽŻàŽ‚ àŽšà”†àŽŻà”àŽŻà”àŽ•. àŽ…àŽ”àŽ°à”àŽŸà”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ‚ àŽ‰àŽȘàŽŻà”‹àŽ—àŽżàŽšà”àŽšà” àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•à”‹àŽĄà” àŽžà”â€ŒàŽ•àŽŸà”» àŽšà”†àŽŻà”àŽŻà”àŽ•àŽŻà”àŽ‚ àŽšà”†àŽŻà”àŽŻàŽŸàŽ‚.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àŽ•à”‚àŽŸà”àŽ€à”œ àŽ…àŽ±àŽżàŽŻà”àŽ•", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} àŽŽàŽšà”àŽšàŽŻàŽŸàŽłà”àŽźàŽŸàŽŻàŽż àŽ†àŽŠà”àŽŻàŽŸàŽ”àŽžàŽŸàŽšàŽ‚ àŽŽà”»àŽ•à”àŽ°àŽżàŽȘà”àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”œ àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽšà”àŽ±àŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”», àŽ…àŽ”àŽ°à”àŽŸà”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ”à”àŽźàŽŸàŽŻàŽż àŽźà”àŽ•àŽłàŽżàŽČà”àŽłà”àŽł àŽ•àŽłà”Œ àŽ•àŽŸà”ŒàŽĄà” àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽ€à”àŽ€à”àŽ•àŽŻà”àŽ‚ àŽ…àŽ•à”àŽ•àŽ™à”àŽ™à”Ÿ àŽ€àŽŸàŽ°àŽ€àŽźà”àŽŻàŽ‚ àŽšà”†àŽŻà”àŽŻà”àŽ•àŽŻà”àŽ‚ àŽšà”†àŽŻà”àŽŻà”‚. àŽ‡àŽ” àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽšà”àŽšàŽżàŽČà”àŽČà”†àŽ™à”àŽ•àŽżà”œ, àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘàŽ±à”àŽ•àŽłà”àŽŸà”† àŽ…àŽŸà”àŽ€à”àŽ€ àŽȘà”†àŽŻà”Œ àŽȘàŽ°à”€àŽ•à”àŽ·àŽżàŽšà”àŽšà” àŽšà”‹àŽ•à”àŽ•à”àŽ•. àŽ’àŽ°à” àŽȘà”†àŽŻà”Œ àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽŸàŽŸà”œ àŽźàŽ€àŽż.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} àŽŽàŽšà”àŽšàŽŻàŽŸàŽłà”àŽźàŽŸàŽŻàŽż àŽ†àŽŠà”àŽŻàŽ”àŽžàŽŸàŽšàŽ‚ àŽŽà”»àŽ•à”àŽ°àŽżàŽȘà”àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”œ àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽšà”àŽ±àŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”» àŽ…àŽ”àŽ°à”àŽŸà”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ”à”àŽźàŽŸàŽŻàŽż àŽźà”àŽ•àŽłàŽżàŽČà”àŽłà”àŽł àŽ…àŽ•à”àŽ•àŽ™à”àŽ™à”Ÿ àŽ€àŽŸàŽ°àŽ€àŽźà”àŽŻàŽ‚ àŽšà”†àŽŻà”àŽŻà”àŽ•. àŽ…àŽ”àŽ°à”àŽŸà”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ‚ àŽ‰àŽȘàŽŻà”‹àŽ—àŽżàŽšà”àŽšà” àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•à”‹àŽĄà” àŽžà”â€ŒàŽ•àŽŸà”» àŽšà”†àŽŻà”àŽŻà”àŽ•àŽŻà”àŽ‚ àŽšà”†àŽŻà”àŽŻàŽŸàŽ‚.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘàŽ±à”àŽ•àŽłàŽżàŽČà”† àŽźàŽŸàŽ±à”àŽ±àŽ™à”àŽ™à”Ÿ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal-à”œ àŽ”àŽ°àŽŸàŽšàŽżàŽ°àŽżàŽ•à”àŽ•à”àŽšà”àŽš àŽžà”àŽ”àŽ•àŽŸàŽ°à”àŽŻàŽ€àŽŸ àŽšàŽŻàŽ™à”àŽ™à”Ÿ àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽšàŽ•à”àŽ·àŽźàŽźàŽŸàŽ•à”àŽ•àŽŸà”» àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘàŽ±à”àŽ•à”Ÿ àŽ•àŽŸàŽČàŽŸàŽšà”àŽžà”ƒàŽ€àŽźàŽŸàŽŻàŽż àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšà”.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘàŽ±à”àŽ•à”Ÿ àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽšà”àŽ±àŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”», àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•à”‹à”șàŽŸàŽŸàŽ•à”àŽ±à”àŽ±àŽżàŽšà”àŽ±à”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ”à”àŽźàŽŸàŽŻàŽż àŽ•àŽłà”Œ àŽ•àŽŸà”ŒàŽĄà” àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽ€à”àŽ€à”àŽ•. àŽ‡àŽ” àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽšà”àŽšàŽżàŽČà”àŽČà”†àŽ™à”àŽ•àŽżà”œ, àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘàŽ±à”àŽ•àŽłà”àŽŸà”† àŽ…àŽŸà”àŽ€à”àŽ€ àŽȘà”†àŽŻà”Œ àŽȘàŽ°à”€àŽ•à”àŽ·àŽżàŽšà”àŽšà” àŽšà”‹àŽ•à”àŽ•à”àŽ•. àŽ’àŽ°à” àŽȘà”†àŽŻà”Œ àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽŸàŽŸà”œ àŽźàŽ€àŽż.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àŽžàŽčàŽŸàŽŻàŽ‚ àŽ†àŽ”àŽ¶à”àŽŻàŽźà”àŽŁà”àŽŸà”‹?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àŽźàŽšàŽžà”àŽžàŽżàŽČàŽŸàŽŻàŽż", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽˆ àŽ”à”àŽŻàŽ•à”àŽ€àŽżàŽŻà”àŽźàŽŸàŽŻàŽż àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽ•à”ˆàŽźàŽŸàŽ±àŽż àŽ•àŽŽàŽżàŽŻà”àŽźà”àŽȘà”‹à”Ÿ àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ àŽžà”ƒàŽ·à”àŽŸàŽżàŽ•à”àŽ•àŽȘà”àŽȘà”†àŽŸà”àŽ‚.", @@ -1267,10 +1359,6 @@ "messageformat": "àŽžàŽźà”€àŽȘàŽ•àŽŸàŽČ àŽźà”€àŽĄàŽżàŽŻ àŽ•àŽŸàŽŁà”àŽ•", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} àŽŽàŽšà”àŽšàŽ€à”àŽźàŽŸàŽŻà”àŽłà”àŽł àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽŽà”»àŽĄà”-àŽŸà”-àŽŽà”»àŽĄà” àŽŽà”»àŽ•à”àŽ°àŽżàŽȘà”â€ŒàŽ·à”» àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽšà”àŽ±àŽȘà”àŽȘàŽżàŽ•à”àŽ•à”àŽšà”àŽšàŽ€àŽżàŽšà”, àŽźà”àŽ•àŽłàŽżà”œ àŽšà”œàŽ•àŽżàŽŻàŽżàŽŸà”àŽŸà”àŽłà”àŽł àŽšàŽźà”àŽȘàŽ°à”àŽ•à”Ÿ àŽ…àŽ”àŽ°à”àŽŸà”† àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ€à”àŽ€àŽżàŽČà”† àŽšàŽźà”àŽȘàŽ°à”àŽ•àŽłà”àŽźàŽŸàŽŻàŽż àŽ’àŽ€à”àŽ€à” àŽšà”‹àŽ•à”àŽ•à”àŽ•. àŽ…àŽ”à”ŒàŽ•à”àŽ•à” àŽźà”àŽ•àŽłàŽżàŽČà”àŽłà”àŽł àŽ•à”àŽŻà”‚àŽ†à”Œ àŽ•à”‹àŽĄà” àŽžà”â€ŒàŽ•àŽŸà”» àŽšà”†àŽŻà”àŽŻà”àŽ•àŽŻà”àŽ‚ àŽšà”†àŽŻà”àŽŻàŽŸàŽ‚.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àŽˆ àŽ•à”‹à”șâ€ŒàŽŸàŽŸàŽ•à”àŽ±à”àŽ±à”àŽźàŽŸàŽŻàŽż àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽ‡àŽ€à”àŽ”àŽ°à”† àŽ’àŽ°à” àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™àŽłà”â€-àŽ‰àŽ‚ àŽ•à”ˆàŽźàŽŸàŽ±àŽżàŽŻàŽżàŽŸà”àŽŸàŽżàŽČà”àŽČ. àŽ†àŽŠà”àŽŻ àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚-àŽ€à”àŽ€àŽżàŽšà” àŽ¶à”‡àŽ·àŽ‚ àŽ…àŽ”àŽ°à”àŽźàŽŸàŽŻà”àŽłà”àŽł àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ àŽČàŽ­à”àŽŻàŽźàŽŸàŽ•à”àŽ‚." }, @@ -1334,17 +1422,17 @@ "messageformat": "àŽ”àŽżàŽ”àŽ°àŽ‚", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”‚", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”‚", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àŽšàŽŸàŽ±à”àŽ±à” àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽŁà”‹?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽŁà”‹?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àŽˆ àŽšàŽŸàŽ±à”àŽ±à” àŽˆ àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ€à”àŽ€àŽżà”œ àŽšàŽżàŽšà”àŽšà” àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”àŽ‚.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àŽˆ àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ€à”àŽ€àŽżà”œ àŽšàŽżàŽšà”àŽšà” àŽˆ àŽšàŽŸàŽ±à”àŽ±àŽżàŽČà”† àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽȘà”àŽȘà”†àŽŸà”àŽ‚. àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽżàŽŻàŽ€àŽżàŽšà” àŽ¶à”‡àŽ·àŽ”à”àŽ‚ àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•à” àŽˆ àŽšàŽŸàŽ±à”àŽ±à” àŽ€àŽżàŽ°àŽŻàŽŸàŽšàŽŸàŽ•à”àŽ‚.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ”àŽżàŽŸà”àŽ•", @@ -1438,6 +1526,14 @@ "messageformat": "àŽ°àŽŁà”àŽŸà” àŽšàŽŸàŽ±à”àŽ±à”àŽ•à”ŸàŽ•à”àŽ•à”àŽźà”àŽłà”àŽł àŽžàŽšà”àŽŠà”‡àŽ¶ àŽšàŽ°àŽżàŽ€à”àŽ°àŽ‚ àŽ‡àŽ”àŽżàŽŸà”† àŽźà”†à”ŒàŽœà” àŽšà”†àŽŻà”àŽ€àŽżàŽŸà”àŽŸà”àŽŁà”àŽŸà”.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} àŽŽàŽšà”àŽš àŽ«à”‹à”ș àŽšàŽźà”àŽȘà”Œ {conversationTitle} àŽŽàŽšà”àŽšàŽŻàŽŸàŽłà”àŽŸà”‡àŽ€àŽŸàŽŁà”. àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽ°àŽŁà”àŽŸà”àŽȘà”‡àŽ°à”àŽ‚ {sharedGroup} àŽŽàŽšà”àŽšàŽ€àŽżàŽČà”† àŽ…àŽ‚àŽ—àŽ™à”àŽ™àŽłàŽŸàŽŁà”.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} àŽŽàŽšà”àŽšàŽŻàŽŸàŽłà”àŽŸà”† àŽšàŽźà”àŽȘàŽ±àŽŸàŽŁà”", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àŽ‰àŽŠà”àŽ§àŽ°àŽżàŽšà”àŽš àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚-àŽ€à”àŽ€àŽżà”œ àŽšàŽżàŽšà”àŽšà”àŽłà”àŽł àŽšàŽżàŽ€à”àŽ°àŽ€à”àŽ€àŽżàŽšà”àŽ±à”† àŽČàŽ˜à”àŽšàŽżàŽ€à”àŽ°àŽ‚", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽ”àŽżàŽłàŽżàŽ•à”àŽ•à”àŽ•", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àŽ•à”‹à”Ÿ àŽ†àŽ°àŽ‚àŽ­àŽżàŽ•à”àŽ•à”àŽ•", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àŽ•à”‹àŽłàŽżà”œ àŽšà”‡àŽ°à”àŽ•", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àŽ•à”‹àŽłàŽżà”œ àŽšàŽżàŽ°àŽ”àŽ§àŽż àŽ†àŽłà”àŽ•àŽłà”àŽłà”àŽłàŽ€àŽżàŽšàŽŸà”œ àŽźà”ˆàŽ•à”àŽ°à”‹àŽ«à”‹à”ș àŽźà”àŽŻà”‚àŽŸà”àŽŸà” àŽšà”†àŽŻà”àŽ€àŽżàŽ°àŽżàŽ•à”àŽ•à”àŽšà”àŽšà”", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àŽ•à”‹à”Ÿ àŽ…àŽ±àŽżàŽŻàŽżàŽȘà”àŽȘà”àŽ•à”Ÿ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àŽ•à”‹à”Ÿ àŽšàŽżàŽ±àŽžà”àŽžà”", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àŽ•à”àŽŻàŽŸàŽźàŽ±", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àŽšà”‡àŽ°à”àŽ•", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àŽ†àŽ°àŽ‚àŽ­àŽ‚", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àŽ•à”‹à”Ÿ àŽšàŽżàŽ±àŽžà”àŽžà”", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àŽ•àŽŸàŽźàŽ± àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽšàŽ°àŽčàŽżàŽ€àŽźàŽŸàŽŁà”", @@ -1621,10 +1725,6 @@ "messageformat": "àŽ•à”àŽŻàŽŸàŽźàŽ± àŽ“à”ș àŽšà”†àŽŻà”àŽŻà”àŽ•", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àŽźà”àŽŻà”‚àŽŸà”àŽŸà” àŽšà”†àŽŻà”àŽŻà”àŽ•", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àŽźà”ˆàŽ•à”àŽ°à”‹àŽ«à”‹à”ș àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽšàŽ°àŽčàŽżàŽ€àŽźàŽŸàŽŁà”", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àŽźà”ˆàŽ•à”àŽ•à” àŽ…à”șàŽźà”àŽŻà”‚àŽŸà”àŽŸà” àŽšà”†àŽŻà”àŽŻà”àŽ•", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àŽȘàŽ™à”àŽ•àŽżàŽŸà”àŽ•", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àŽ…àŽȘà”àŽ°àŽŸàŽȘà”àŽ€àŽźàŽŸàŽ•à”àŽ•àŽż àŽ…àŽ”àŽ€àŽ°àŽżàŽȘà”àŽȘàŽżàŽ•à”àŽ•à”àŽšà”àŽšà”", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àŽ…àŽ”àŽ€àŽ°àŽżàŽȘà”àŽȘàŽżàŽ•à”àŽ•à”àŽšà”àŽšàŽ€à” àŽšàŽżà”ŒàŽ€à”àŽ€à”àŽ•", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àŽ±àŽżàŽ‚àŽ—à”", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àŽȘàŽ™à”àŽ•à”†àŽŸà”àŽ•à”àŽ•à”àŽšà”àŽšàŽ”àŽ°à”† àŽ”àŽżàŽłàŽżàŽ•à”àŽ•àŽŸà”» àŽ•àŽŽàŽżàŽŻàŽŸàŽ€à”àŽ€àŽ€à”àŽ° àŽ”àŽČà”àŽ€àŽŸàŽŁà” àŽ—à”àŽ°à”‚àŽȘà”àŽȘà”.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àŽ±àŽżàŽ‚àŽ—à” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšàŽ€à” àŽȘà”àŽ°àŽŸàŽȘà”â€ŒàŽ€àŽźàŽŸàŽ•à”àŽ•à”àŽ•", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àŽ±àŽżàŽ‚àŽ—àŽżàŽ‚àŽ—à” àŽ“àŽ«àŽŸàŽ•à”àŽ•à”àŽ•", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àŽ±àŽżàŽ‚àŽ—àŽżàŽ‚àŽ—à” àŽ“àŽŁàŽŸàŽ•à”àŽ•à”àŽ•", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àŽ•à”‚àŽŸà”àŽ€à”œ àŽ“àŽȘà”â€ŒàŽ·àŽšà”àŽ•à”Ÿ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™à”Ÿ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•à”àŽŻàŽŸàŽźàŽ± àŽ“àŽ«àŽŸàŽŁà”", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ àŽ•àŽŸàŽŁà”àŽ•", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àŽžà”àŽ°àŽ•à”àŽ·àŽŸ àŽšàŽźà”àŽȘà”Œ àŽ•àŽŸàŽŁà”àŽ•", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "àŽ«à”‹à”ș àŽšàŽźà”àŽȘà”Œ àŽ•àŽŁà”àŽŸà”†àŽ€à”àŽ€àŽŸàŽšàŽŸàŽŻàŽżàŽČà”àŽČ. àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•àŽŁàŽ•à”àŽ·à”» àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽš àŽ¶à”‡àŽ·àŽ‚ àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽ¶à”àŽ°àŽźàŽżàŽ•à”àŽ•à”àŽ•.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽˆ àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽ…àŽŻàŽšà”àŽšà” 3 àŽźàŽŁàŽżàŽ•à”àŽ•à”‚àŽ±àŽżàŽšàŽ•àŽ‚ àŽźàŽŸàŽ€à”àŽ°àŽźà”† àŽŽàŽĄàŽżàŽ±à”àŽ±à”àŽ•à”Ÿ àŽŹàŽŸàŽ§àŽ•àŽźàŽŸàŽ•à”àŽ•àŽŸàŽšàŽŸàŽ•à”‚.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽˆ àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽ…àŽŻàŽšà”àŽšà” 24 àŽźàŽŁàŽżàŽ•à”àŽ•à”‚àŽ±àŽżàŽšà”àŽłà”àŽłàŽżà”œ àŽźàŽŸàŽ€à”àŽ°àŽźà”‡ àŽŽàŽĄàŽżàŽ±à”àŽ±à”àŽ•à”Ÿ àŽŹàŽŸàŽ§àŽ•àŽźàŽŸàŽ•à”àŽ•àŽŸàŽšàŽŸàŽ•à”‚.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àŽˆ àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽż.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àŽȘà”àŽ°àŽŠà”ŒàŽ¶àŽżàŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”» àŽ•àŽŽàŽżàŽŻàŽŸàŽ€à”àŽ€ àŽ…àŽ€à”àŽ°àŽŻà”àŽ‚ àŽ”àŽČà”àŽ€àŽŸàŽŁà” àŽ…àŽ±à”àŽ±àŽŸàŽšà”àŽšà”àŽźà”†àŽšà”àŽ±à”.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àŽȘà”àŽ°àŽŠà”ŒàŽ¶àŽżàŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”» àŽ•àŽŽàŽżàŽŻàŽŸàŽ€à”àŽ€ àŽ…àŽ€à”àŽ°àŽŻà”àŽ‚ àŽ”àŽČà”àŽ€àŽŸàŽŁà” àŽšàŽżàŽČ àŽ…àŽ±à”àŽ±àŽŸàŽšà”àŽšà”àŽźà”†àŽšà”àŽ±à”àŽ•à”Ÿ.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àŽžàŽ‚àŽ­àŽŸàŽ”àŽšàŽŸ àŽ”àŽżàŽ¶àŽŠàŽŸàŽ‚àŽ¶àŽ™à”àŽ™à”Ÿ àŽČàŽ­à”àŽŻàŽźàŽŸàŽ•à”àŽ•àŽŸàŽšàŽŸàŽŻàŽżàŽČà”àŽČ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal àŽŹà”€àŽ±à”àŽ±àŽŸ àŽźàŽŸàŽ€à”àŽ°àŽ‚", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ™à”àŽ™à”Ÿ àŽŽàŽĄàŽżàŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”œ Signal àŽŹà”€àŽ±à”àŽ±àŽŸ àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€àŽŸàŽ•à”àŽ•à”ŸàŽ•à”àŽ•à” àŽźàŽŸàŽ€à”àŽ°àŽ‚. àŽšàŽżàŽ™à”àŽ™àŽłà”†àŽŸàŽ°à” àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽŽàŽĄàŽżàŽ±à”àŽ±à” àŽšà”†àŽŻà”â€ŒàŽ€àŽŸà”œ, Signal àŽŹà”€àŽ±à”àŽ±àŽŻà”àŽŸà”† àŽàŽ±à”àŽ±àŽ”à”àŽ‚ àŽȘà”àŽ€àŽżàŽŻ àŽȘàŽ€àŽżàŽȘà”àŽȘàŽżàŽČà”àŽłà”àŽłàŽ”à”ŒàŽ•à”àŽ•à” àŽźàŽŸàŽ€à”àŽ°àŽźà”† àŽ…àŽ€à” àŽ•àŽŸàŽŁàŽŸàŽšàŽŸàŽ•à”‚.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽŽàŽĄàŽżàŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”àŽ•", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”†àŽŸàŽ°à” àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽŽàŽĄàŽżàŽ±à”àŽ±à” àŽšà”†àŽŻà”â€ŒàŽ€àŽŸà”œ, Signal àŽŹà”€àŽ±à”àŽ±àŽŻà”àŽŸà”† àŽàŽ±à”àŽ±àŽ”à”àŽ‚ àŽȘà”àŽ€àŽżàŽŻ àŽȘàŽ€àŽżàŽȘà”àŽȘàŽżàŽČà”àŽłà”àŽłàŽ”à”ŒàŽ•à”àŽ•à” àŽźàŽŸàŽ€à”àŽ°àŽźà”† àŽ…àŽ€à” àŽ•àŽŸàŽŁàŽŸàŽšàŽŸàŽ•à”‚. àŽšàŽżàŽ™à”àŽ™àŽłà”†àŽŸàŽ°à” àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽŽàŽĄàŽżàŽ±à”àŽ±à” àŽšà”†àŽŻà”â€ŒàŽ€à”àŽ”à”†àŽšà”àŽšà” àŽ…àŽ”à”ŒàŽ•à”àŽ•à” àŽ•àŽŸàŽŁàŽŸàŽšàŽŸàŽ•à”àŽ‚.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àŽ‡à”»àŽ•àŽźàŽżàŽ‚àŽ—à” àŽ”à”€àŽĄàŽżàŽŻà”‹ àŽ•à”‹à”Ÿ...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àŽ”àŽŸà”àŽŸà”àŽ—à”‹àŽŻàŽżàŽ‚àŽ—à” àŽ”à”‹àŽŻà”â€ŒàŽžà” àŽ•à”‹à”Ÿ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àŽ”àŽŸà”àŽŸà”àŽ—à”‹àŽŻàŽżàŽ‚àŽ—à” àŽ”à”€àŽĄàŽżàŽŻà”‹ àŽ•à”‹à”Ÿ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àŽšàŽżàŽ™à”àŽ™àŽłà”† àŽ”àŽżàŽłàŽżàŽ•à”àŽ•à”àŽšà”àŽšà”", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽ•àŽŁàŽ•à”àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšà”...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} àŽ†à”Ÿ} other {{count,number} àŽȘà”‡àŽ°à”â€}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àŽ“àŽĄàŽżàŽŻà”‹ àŽ•à”‹à”Ÿ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àŽ…àŽ”àŽžàŽŸàŽšàŽ‚", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àŽ”àŽżàŽŸà”àŽŸà” àŽȘà”‹àŽ•à”àŽ•", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àŽźà”ˆàŽ•à”àŽ•à” àŽ“àŽ«àŽŸàŽŁà”", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àŽźà”ˆàŽ•à”àŽ•à” àŽ“àŽŁàŽŸàŽŁà”", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àŽ±àŽżàŽ‚àŽ—àŽżàŽ‚àŽ—à” àŽ“àŽŁàŽŸàŽŁà”", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àŽ±àŽżàŽ‚àŽ—àŽżàŽ‚àŽ—à” àŽ“àŽ«àŽŸàŽŁà”", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽŁàŽ™à”àŽ™à”Ÿ", @@ -3468,13 +3668,25 @@ "messageformat": "àŽ«à”à”ŸàŽžà”àŽ•à”àŽ°à”€à”» àŽ•à”‹à”Ÿ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àŽ—à”àŽ°àŽżàŽĄà” àŽ•àŽŸàŽŽà”àŽšàŽŻàŽżàŽČà”‡àŽ•à”àŽ•à” àŽźàŽŸàŽ±à”àŽ•", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àŽ•àŽŸàŽŽà”àŽš àŽźàŽŸàŽ±à”àŽ±à”àŽ•", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àŽžà”àŽȘà”€àŽ•à”àŽ•à”Œ àŽ•àŽŸàŽŽà”àŽšàŽŻàŽżàŽČà”‡àŽ•à”àŽ•à” àŽźàŽŸàŽ±à”àŽ•", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àŽ—à”àŽ°àŽżàŽĄà” àŽ•àŽŸàŽŽà”àŽš", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àŽžà”ˆàŽĄà”â€ŒàŽŹàŽŸà”Œ àŽ•àŽŸàŽŽà”àŽš", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àŽžà”àŽȘà”€àŽ•à”àŽ•à”Œ àŽ•àŽŸàŽŽà”àŽš", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àŽ•àŽŸàŽŽà”àŽš àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽ€à”", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àŽ•à”‹à”Ÿ àŽ‰àŽȘà”‡àŽ•à”àŽ·àŽżàŽ•à”àŽ•à”àŽ•", @@ -3576,6 +3788,14 @@ "messageformat": "àŽ¶àŽ°àŽż", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚ àŽŽàŽĄàŽżàŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻàŽŸàŽšàŽŸàŽ•àŽżàŽČà”àŽČ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àŽˆ àŽžàŽšà”àŽŠà”‡àŽ¶àŽ€à”àŽ€àŽżàŽšà” {max,number} àŽŽàŽĄàŽżàŽ±à”àŽ±à”àŽ•à”Ÿ àŽźàŽŸàŽ€à”àŽ°àŽźà”† àŽ”àŽ°à”àŽ€à”àŽ€àŽŸàŽšàŽŸàŽ•à”‚.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àŽ•à”àŽ·àŽźàŽżàŽ•à”àŽ•àŽŁàŽ‚, àŽ† sgnl:// àŽČàŽżàŽ™à”àŽ•à” àŽ…à”ŒàŽ€à”àŽ„àŽźàŽżàŽČà”àŽČ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ”à”àŽźàŽŸàŽŻàŽż àŽŹàŽšà”àŽ§àŽȘà”àŽȘà”†àŽŸà”àŽŸà” àŽŽàŽšà”àŽ€à”‹ àŽȘàŽżàŽ¶àŽ•à”àŽŁà”àŽŸàŽŸàŽŻàŽż, àŽ‡àŽ€à” àŽšàŽżàŽČàŽ”àŽżà”œ àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ…àŽ•à”àŽ•à”—àŽŁà”àŽŸàŽżàŽČà”‡àŽ•à”àŽ•à” àŽ…àŽžà”ˆà”» àŽšà”†àŽŻà”àŽ€àŽżàŽŸà”àŽŸàŽżàŽČà”àŽČ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”àŽ•", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àŽŻà”‚àŽžà”Œ àŽȘà”‡àŽ°à” àŽžà”ƒàŽ·à”àŽŸàŽżàŽ•à”àŽ•à”àŽ•", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR àŽ•à”‹àŽĄà” àŽ…àŽČà”àŽČà”†àŽ™à”àŽ•àŽżà”œ àŽČàŽżàŽ™à”àŽ•à”", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽȘà”àŽšàŽƒàŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽżàŽ•à”àŽ•à”‡àŽŁà”àŽŸàŽ€à”àŽŁà”àŽŸà”", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽź àŽČàŽżàŽ™à”àŽ•à” àŽȘà”àŽšàŽƒàŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽżàŽ•à”àŽ•à”‡àŽŁà”àŽŸàŽ€à”àŽŁà”àŽŸà”", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽȘàŽ™à”àŽ•àŽżàŽŸà”àŽ•", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”àŽ•", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àŽ‡àŽ€à” àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽšà”€àŽ•à”àŽ•àŽ‚ àŽšà”†àŽŻà”àŽŻà”àŽ‚, àŽ…àŽ€à”‹àŽŸà”† àŽźàŽ±à”àŽ±à” àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€àŽŸàŽ•à”àŽ•à”ŸàŽ•à”àŽ•à” àŽ…àŽ€à” àŽ…àŽ”àŽ•àŽŸàŽ¶àŽȘà”àŽȘà”†àŽŸàŽŸàŽšàŽŸàŽ•à”àŽ‚. àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•à” àŽ‰àŽ±àŽȘà”àŽȘàŽŸàŽŁà”‹?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àŽ‡àŽ€à” àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•à”àŽ•àŽŻà”àŽ‚ àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† QR àŽ•à”‹àŽĄà”àŽ‚ àŽČàŽżàŽ™à”àŽ•à”àŽ‚ àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽšàŽ°àŽčàŽżàŽ€àŽźàŽŸàŽ•à”àŽ•à”àŽ•àŽŻà”àŽ‚ àŽšà”†àŽŻà”àŽŻà”àŽ‚. “{username}” àŽźàŽ±à”àŽ±à”àŽłà”àŽłàŽ”à”ŒàŽ•à”àŽ•à” àŽ•à”àŽČà”†àŽŻàŽżàŽ‚ àŽšà”†àŽŻà”àŽŻàŽŸàŽšàŽŸàŽŻàŽż àŽČàŽ­à”àŽŻàŽźàŽŸàŽ•à”àŽ‚. àŽ‰àŽ±àŽȘà”àŽȘàŽŸàŽŁà”‹?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àŽšàŽżàŽ™à”àŽ™à”ŸàŽ•à”àŽ•à” àŽ‡àŽšàŽżàŽźà”àŽ€à”œ àŽžà”àŽ±à”àŽ±à”‹àŽ±àŽżàŽ•à”Ÿ àŽȘàŽ™à”àŽ•àŽżàŽŸàŽŸàŽšà”‹ àŽ•àŽŸàŽŁàŽŸàŽšà”‹ àŽ•àŽŽàŽżàŽŻàŽżàŽČà”àŽČ. àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽ…àŽŸà”àŽ€à”àŽ€àŽżàŽŸà”† àŽȘàŽ™à”àŽ•àŽżàŽŸà”àŽŸ àŽžà”àŽ±à”àŽ±à”‹àŽ±àŽż àŽ…àŽȘà”â€ŒàŽĄà”‡àŽ±à”àŽ±à”àŽ•àŽłà”àŽ‚ àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ•àŽȘà”àŽȘà”†àŽŸà”àŽ‚.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àŽ­àŽŸàŽ·", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àŽ­àŽŸàŽ·", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àŽžàŽżàŽžà”àŽ±à”àŽ±àŽ‚ àŽ­àŽŸàŽ·", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àŽ­àŽŸàŽ·àŽ•à”Ÿ àŽ€àŽżàŽ°àŽŻà”àŽ•", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "\"{searchTerm}\" àŽŽàŽšà”àŽšàŽ€àŽżàŽšà” àŽ«àŽČàŽ™à”àŽ™àŽłà”†àŽŸàŽšà”àŽšà”àŽźàŽżàŽČà”àŽČ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àŽžàŽœà”àŽœàŽźàŽŸàŽ•à”àŽ•à”àŽ•", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àŽŹàŽŸàŽ§àŽ•àŽźàŽŸàŽ•à”àŽ•àŽŸà”» Signal àŽ±à”€àŽžà”àŽ±à”àŽ±àŽŸà”ŒàŽŸà”àŽŸà” àŽšà”†àŽŻà”àŽŻà”àŽ•", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àŽ­àŽŸàŽ· àŽźàŽŸàŽ±à”àŽ±àŽŸà”», àŽ†àŽȘà”àŽȘà” àŽ±à”€àŽžà”àŽ±à”àŽ±àŽŸà”ŒàŽŸà”àŽŸà” àŽšà”†àŽŻà”àŽŻà”‡àŽŁà”àŽŸàŽ€à”àŽŁà”àŽŸà”.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àŽ±à”€àŽžà”àŽ±à”àŽ±àŽŸà”ŒàŽŸà”àŽŸà” àŽšà”†àŽŻà”àŽŻà”àŽ•", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} àŽŽàŽšà”àŽš àŽȘàŽ€àŽżàŽȘà”àŽȘàŽżàŽČà”‡àŽ•à”àŽ•à”àŽłà”àŽł àŽ…àŽȘà”â€ŒàŽĄà”‡àŽ±à”àŽ±à” àŽČàŽ­à”àŽŻàŽźàŽŸàŽŁà”", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽŁàŽ™à”àŽ™à”Ÿ àŽžàŽ‚àŽ°àŽ•à”àŽ·àŽżàŽ•à”àŽ•à”àŽźà”àŽȘà”‹à”Ÿ àŽ’àŽ°à” àŽȘàŽżàŽ¶àŽ•à”àŽŁà”àŽŸàŽŸàŽŻàŽż. àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽ¶à”àŽ°àŽźàŽżàŽ•à”àŽ•à”àŽ•.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àŽžàŽšà”àŽŠà”‡àŽ¶àŽ‚", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àŽ•à”‚àŽŸà”àŽ€à”œ àŽžà”àŽ±à”àŽ±à”ˆàŽČà”àŽ•à”Ÿ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àŽȘà”àŽšàŽƒàŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽżàŽ•à”àŽ•à”àŽ•", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àŽšà”†àŽŻà”â€ŒàŽ€à”", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽź àŽČàŽżàŽ™à”àŽ•à” àŽšàŽżàŽ±àŽ‚, {total,number}-à”œ {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àŽšàŽżàŽ™à”àŽ™à”Ÿ QR àŽ•à”‹àŽĄà” àŽȘà”àŽšàŽƒàŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽżàŽ•à”àŽ•à”àŽ• àŽ†àŽŁà”†àŽ™à”àŽ•àŽżà”œ, àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽšàŽżàŽČàŽ”àŽżàŽČà”àŽłà”àŽł QR àŽ•à”‹àŽĄà”àŽ‚ àŽČàŽżàŽ™à”àŽ•à”àŽ‚ àŽȘàŽżàŽšà”àŽšà”€àŽŸà” àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽżàŽ•à”àŽ•àŽżàŽČà”àŽČ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àŽČàŽżàŽ™à”àŽ•à” àŽ±à”€àŽžà”†àŽ±à”àŽ±à” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšà”...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR àŽ•à”‹àŽĄà”àŽ‚ àŽČàŽżàŽ™à”àŽ•à”àŽ‚ àŽžàŽœà”àŽœà”€àŽ•àŽ°àŽżàŽšà”àŽšàŽżàŽŸà”àŽŸàŽżàŽČà”àŽČ. àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽšà”†àŽ±à”àŽ±à”â€ŒàŽ”à”ŒàŽ•à”àŽ•à” àŽ•àŽŁàŽ•à”àŽ·à”» àŽȘàŽ°àŽżàŽ¶à”‹àŽ§àŽżàŽšà”àŽš àŽ¶à”‡àŽ·àŽ‚ àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽ¶à”àŽ°àŽźàŽżàŽ•à”àŽ•à”àŽ•.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† Signal àŽ‰àŽȘàŽŻà”‹àŽ•à”àŽ€à”ƒàŽšàŽŸàŽźàŽ‚ àŽžàŽœà”àŽœà”€àŽ•àŽ°àŽżàŽ•à”àŽ•à”àŽ•", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "àŽ”à”€àŽŁà”àŽŸà”àŽ‚ àŽ…àŽŻàŽ•à”àŽ•à”àŽ•", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àŽ•à”‚àŽŸà”àŽ€à”œ àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽšàŽ™à”àŽ™à”Ÿ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àŽ•à”‹àŽłà”àŽ•à”Ÿ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àŽȘà”àŽ€àŽżàŽŻ àŽ•à”‹à”Ÿ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àŽȘà”àŽ€àŽżàŽŻ àŽ•à”‹à”Ÿ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àŽ•à”‚àŽŸà”àŽ€à”œ àŽȘà”àŽ°àŽ”à”ŒàŽ€à”àŽ€àŽšàŽ™à”àŽ™à”Ÿ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àŽ•à”‹à”Ÿ àŽšàŽ°àŽżàŽ€à”àŽ°àŽ‚ àŽźàŽŸàŽŻà”àŽ•à”àŽ•à”àŽ•", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àŽ•à”‹à”Ÿ àŽšàŽ°àŽżàŽ€à”àŽ°àŽ‚ àŽźàŽŸàŽŻà”àŽ•à”àŽ•àŽŁà”‹?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àŽ‡àŽ€à”, àŽ•à”‹à”Ÿ àŽšàŽ°àŽżàŽ€à”àŽ°àŽ‚ àŽ¶àŽŸàŽ¶à”àŽ”àŽ€àŽźàŽŸàŽŻàŽż àŽźàŽŸàŽŻà”àŽ•à”àŽ•à”àŽ‚", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àŽźàŽŸàŽŻà”â€ŒàŽ•à”àŽ•à”àŽ•", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àŽ•à”‹à”Ÿ àŽšàŽ°àŽżàŽ€à”àŽ°àŽ‚ àŽ•à”àŽČàŽżàŽŻà”Œ àŽšà”†àŽŻà”àŽ€à”", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àŽ•àŽŸàŽŁàŽŸàŽšà”‹ àŽ•à”‹à”Ÿ àŽ€à”àŽŸàŽ™à”àŽ™àŽŸàŽšà”‹ àŽ•à”àŽČàŽżàŽ•à”àŽ•à” àŽšà”†àŽŻà”àŽŻà”àŽ•", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àŽ€àŽżàŽ°àŽŻà”œ", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àŽźàŽżàŽžà”â€ŒàŽĄà” àŽȘà”àŽ°àŽ•àŽŸàŽ°àŽ‚ àŽ…àŽŸà”àŽ•à”àŽ•à”àŽ•", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àŽŸà”‹àŽ—àŽżà”Ÿ àŽšà”†àŽŻà”àŽŻà”àŽ•", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àŽžàŽźà”€àŽȘàŽ•àŽŸàŽČ àŽ•à”‹àŽłà”àŽ•àŽłà”†àŽŸàŽšà”àŽšà”àŽźàŽżàŽČà”àŽČ. àŽ’àŽ°à” àŽžà”àŽčà”ƒàŽ€à”àŽ€àŽżàŽšà”† àŽ”àŽżàŽłàŽżàŽšà”àŽšà” àŽ€à”àŽŸàŽ™à”àŽ™à”‚.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "\"{query}\" àŽŽàŽšà”àŽšàŽ€àŽżàŽšà” àŽ«àŽČàŽ™à”àŽ™àŽłà”†àŽŸàŽšà”àŽšà”àŽźàŽżàŽČà”àŽČ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àŽ‡à”»àŽ•àŽźàŽżàŽ‚àŽ—à”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àŽ”àŽŸà”àŽŸà”àŽ—à”‹àŽŻàŽżàŽ‚àŽ—à”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àŽźàŽżàŽžà”â€ŒàŽĄà”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹à”Ÿ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àŽžàŽźà”€àŽȘàŽ•àŽŸàŽČ àŽžàŽ‚àŽ­àŽŸàŽ·àŽŁàŽ™à”àŽ™àŽłà”†àŽŸàŽšà”àŽšà”àŽźàŽżàŽČà”àŽČ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "\"{query}\" àŽŽàŽšà”àŽšàŽ€àŽżàŽšà” àŽ«àŽČàŽ™à”àŽ™àŽłà”†àŽŸàŽšà”àŽšà”àŽźàŽżàŽČà”àŽČ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àŽ”àŽŸà”àŽŸà”àŽ—à”‹àŽŻàŽżàŽ‚àŽ—à” àŽ”à”‹àŽŻà”â€ŒàŽžà” àŽ•à”‹à”Ÿ} other {àŽ‡à”»àŽ•àŽźàŽżàŽ‚àŽ—à” àŽ”à”‹àŽŻà”â€ŒàŽžà” àŽ•à”‹à”Ÿ}}} Video {{direction, select, Outgoing {àŽ”àŽŸà”àŽŸà”àŽ—à”‹àŽŻàŽżàŽ‚àŽ—à” àŽ”à”€àŽĄàŽżàŽŻà”‹ àŽ•à”‹à”Ÿ} other {àŽ‡à”»àŽ•àŽźàŽżàŽ‚àŽ—à” àŽ”à”€àŽĄàŽżàŽŻà”‹ àŽ•à”‹à”Ÿ}}} Group {{direction, select, Outgoing {àŽ”àŽŸà”àŽŸà”â€ŒàŽ—à”‹àŽŻàŽżàŽ‚àŽ—à” àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹à”Ÿ} other {àŽ‡à”»àŽ•àŽźàŽżàŽ‚àŽ—à” àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹à”Ÿ}}} other {{direction, select, Outgoing {àŽ”àŽŸà”àŽŸà” àŽ—à”‹àŽŻàŽżàŽ‚àŽ—à” àŽ•à”‹à”Ÿ} other {àŽ‡à”»àŽ•àŽźàŽżàŽ‚àŽ—à” àŽ•à”‡àŽŸà”Ÿ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àŽźàŽżàŽžà”â€ŒàŽĄà” àŽ”à”‹àŽŻà”â€ŒàŽžà” àŽ•à”‹à”Ÿ} Video {àŽ”à”€àŽĄàŽżàŽŻà”‹ àŽ•à”‹à”Ÿ àŽšàŽ·à”â€ŒàŽŸàŽźàŽŸàŽŻàŽż} Group {àŽźàŽżàŽžà”â€ŒàŽĄà” àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹à”Ÿ} other {àŽźàŽżàŽžà”àŽĄà” àŽ•à”‡àŽŸà”Ÿ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àŽ‰àŽ€à”àŽ€àŽ°àŽ‚ àŽČàŽ­àŽżàŽ•à”àŽ•àŽŸàŽ€à”àŽ€ àŽ”à”‹àŽŻà”â€ŒàŽžà” àŽ•à”‡àŽŸà”Ÿ} Video {àŽ‰àŽ€à”àŽ€àŽ°àŽ‚ àŽČàŽ­àŽżàŽ•à”àŽ•àŽŸàŽ€à”àŽ€ àŽ”à”€àŽĄàŽżàŽŻà”‡àŽŸ àŽ•à”‡àŽŸà”Ÿ} Group {àŽ‰àŽ€à”àŽ€àŽ°àŽ‚ àŽšà”œàŽ•àŽŸàŽ€à”àŽ€ àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹à”Ÿ} other {àŽ‰àŽ€à”àŽ€àŽ°àŽ‚ àŽšà”œàŽ•àŽŸàŽ€à”àŽ€ àŽ•à”‹à”Ÿ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àŽšàŽżàŽ°àŽžàŽżàŽšà”àŽš àŽ”à”‹àŽŻàŽżàŽžà” àŽ•à”‹à”Ÿ} Video {àŽšàŽżàŽ°àŽžàŽżàŽšà”àŽš àŽ”à”€àŽĄàŽżàŽŻà”‡àŽŸ àŽ•à”‡àŽŸà”Ÿ} Group {àŽšàŽżàŽ°àŽžàŽżàŽšà”àŽš àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹à”Ÿ} other {àŽšàŽżàŽ°àŽžàŽżàŽšà”àŽš àŽ•à”‹à”Ÿ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {àŽźàŽ±à”àŽ±à” {count,number} àŽ†à”Ÿ àŽŸà”ˆàŽȘà”àŽȘà” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšà”.} other {àŽźàŽ±à”àŽ±à” {count,number} àŽȘà”‡à”Œ àŽŸà”ˆàŽȘà”àŽȘà” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšà”.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àŽȘà”àŽ€àŽżàŽŻàŽ€àŽŸàŽŻàŽż àŽŽàŽšà”àŽ€à”àŽŁà”àŽŸà”", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àŽšà”†àŽ±àŽżàŽŻ àŽźàŽŸàŽ±à”àŽ±àŽ™à”àŽ™àŽłà”àŽ‚ àŽŹàŽ—à” àŽȘàŽ°àŽżàŽčàŽ°àŽżàŽ•à”àŽ•àŽČà”àŽ•àŽłà”àŽ‚ àŽȘà”àŽ°àŽ•àŽŸàŽš àŽźà”†àŽšà”àŽšàŽȘà”àŽȘà”†àŽŸà”àŽ€à”àŽ€àŽČà”àŽ•àŽłà”àŽ‚. Signal àŽ‰àŽȘàŽŻà”‹àŽ—àŽżàŽ•à”àŽ•à”àŽšà”àŽšàŽ€àŽżàŽšà” àŽšàŽšà”àŽŠàŽż!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àŽˆ àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±àŽżà”œ àŽ¶àŽŹà”àŽŠ, àŽ”à”€àŽĄàŽżàŽŻà”‡àŽŸ àŽ•à”‡àŽŸàŽłà”àŽ•à”ŸàŽ•à”àŽ•à”àŽłà”àŽł àŽàŽ€àŽŸàŽšà”àŽ‚ àŽźà”†àŽšà”àŽšàŽȘà”àŽȘà”†àŽŸà”àŽ€à”àŽ€àŽČà”àŽ•à”Ÿ, àŽàŽ€àŽŸàŽšà”àŽ‚ àŽĄà”‹àŽ•à”àŽŻà”àŽźà”†àŽšà”àŽ±à”‡àŽ·à”» àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±à”àŽ•à”Ÿ àŽŽàŽšà”àŽšàŽżàŽ” àŽ‰à”ŸàŽȘà”àŽȘà”†àŽŸà”àŽšà”àŽšà” (àŽšàŽšà”àŽŠàŽż, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "àŽ‡àŽȘà”àŽȘà”‹à”Ÿ àŽšàŽżàŽ™à”àŽ™àŽłà”àŽŸà”† àŽžàŽżàŽžà”àŽ±à”àŽ±àŽ‚ àŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽŁàŽ‚ àŽźàŽŸàŽ±à”àŽ±àŽŸàŽ€à”† àŽ€àŽšà”àŽšà”† àŽšàŽżàŽ™à”àŽ™à”Ÿ àŽ€àŽżàŽ°àŽžà”àŽžà”†àŽŸà”àŽ€à”àŽ€ àŽ­àŽŸàŽ· Signal-à”œ àŽźàŽŸàŽ±à”àŽ±àŽŸàŽ‚ (Signal àŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽŁàŽ‚ >àŽŠà”ƒàŽ¶à”àŽŻàŽźàŽŸàŽ•à”àŽšà”àŽšàŽ€à” > àŽ­àŽŸàŽ·)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àŽ†àŽ°à”†àŽ™à”àŽ•àŽżàŽČà”àŽ‚ àŽ—à”àŽ°à”‚àŽȘà”àŽȘàŽżà”œ àŽȘà”àŽ€à”àŽ€àŽŸàŽŻàŽż àŽšà”‡àŽ°à”àŽšà”àŽšàŽ€à” àŽȘà”‹àŽČà”†àŽŻà”àŽłà”àŽł àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ…àŽȘà”àŽĄà”‡àŽ±à”àŽ±à”àŽ•à”Ÿ àŽŠà”ƒàŽ¶à”àŽŻàŽźàŽŸàŽ•à”àŽšà”àŽš àŽ…àŽ±àŽżàŽŻàŽżàŽȘà”àŽȘà” àŽàŽ•à”àŽ•àŽŁà”àŽ•à”Ÿ àŽžàŽ™à”àŽ™à”Ÿ àŽȘàŽ°àŽżàŽ·à”àŽ•à”àŽ•àŽ°àŽżàŽšà”àŽšà”. àŽĄàŽŸà”ŒàŽ•à”àŽ•à” àŽ€à”€àŽźàŽżàŽČà”àŽ‚ àŽźàŽ±à”àŽ±à”àŽ‚ àŽ†àŽŻàŽżàŽ°àŽżàŽ•à”àŽ•à”àŽźà”àŽȘà”‹à”Ÿ àŽ”àŽŸàŽŻàŽšàŽŸàŽ•à”àŽ·àŽźàŽ€ àŽ”à”ŒàŽŠà”àŽ§àŽżàŽȘà”àŽȘàŽżàŽ•à”àŽ•àŽŸà”» àŽˆ àŽàŽ•à”àŽ•àŽŁà”àŽ•à”Ÿ àŽžàŽčàŽŸàŽŻàŽżàŽ•à”àŽ•à”àŽ‚. àŽźà”àŽźà”àŽȘà”àŽłà”àŽł àŽàŽ•à”àŽ•àŽŁà”àŽ•à”Ÿ àŽ‡àŽ°à”àŽŸà”àŽŸàŽżàŽšà”‹àŽŸà” àŽȘà”†àŽŸàŽ°à”àŽ€à”àŽ€àŽȘà”àŽȘà”†àŽŸà”àŽšà”àŽšàŽ” àŽ†àŽŻàŽżàŽ°à”àŽšà”àŽšàŽżàŽČà”àŽČ. àŽȘà”àŽ€àŽżàŽŻ àŽàŽ•à”àŽ•àŽŁà”àŽ•à”Ÿ àŽ‡àŽ°à”àŽŸà”àŽŸàŽżàŽšà”‹àŽŸà” àŽ‡àŽŽà”àŽ•àŽżàŽšà”àŽšà”‡à”ŒàŽšà”àŽšà” àŽšàŽżà”œàŽ•à”àŽ•à”àŽšà”àŽšàŽ”àŽŻàŽŸàŽŁà”." + "icu:WhatsNew__v6.39--1": { + "messageformat": "MacOS àŽ‰àŽȘàŽ•àŽ°àŽŁàŽ™à”àŽ™àŽłàŽżà”œ àŽšàŽżàŽšà”àŽšà” àŽ•à”‹à”Ÿ àŽČà”‹àŽŹàŽżàŽŻàŽżà”œ àŽšà”‡àŽ°à”àŽźà”àŽȘà”‹à”Ÿ àŽšàŽżàŽČàŽȘà”àŽȘà”‹à”Ÿ àŽšà”‡àŽ°àŽżàŽŸà”àŽšà”àŽš àŽšà”†àŽ±àŽżàŽŻ àŽ•àŽŸàŽČàŽ€àŽŸàŽźàŽžàŽ‚ àŽžàŽ™à”àŽ™à”Ÿ àŽȘàŽ°àŽżàŽčàŽ°àŽżàŽšà”àŽšà”, àŽźà”€àŽ±à”àŽ±àŽżàŽ‚àŽ—àŽżà”œ àŽšà”‡àŽ°àŽŸà”» àŽ…àŽ° àŽžà”†àŽ•à”àŽ•à”»àŽĄà” àŽ”à”ˆàŽ•àŽżàŽŻàŽ€àŽżàŽšà”àŽłà”àŽł àŽ’àŽ°à” àŽ’àŽŽàŽżàŽ•àŽŽàŽżàŽ”à”†àŽ™à”àŽ•àŽżàŽČà”àŽ‚ àŽ‡àŽ€à”‹àŽŸà”† àŽ‡àŽČà”àŽČàŽŸàŽ€àŽŸàŽ•à”àŽ‚." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àŽ†àŽ°à”†àŽ™à”àŽ•àŽżàŽČà”àŽ‚ àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ•à”‹àŽłàŽżà”œ àŽšà”‡àŽ°à”àŽźà”àŽȘà”‹àŽŽà”‹ àŽȘà”àŽ±àŽ€à”àŽ€à”àŽȘà”‹àŽ•à”àŽźà”àŽȘà”‹àŽŽà”‹ àŽ”à”€àŽĄàŽżàŽŻà”‹ àŽŸà”ˆàŽČà”àŽ•à”ŸàŽ•à”àŽ•à”àŽłà”àŽł àŽŸà”àŽ°àŽŸà”»àŽžàŽżàŽ·à”» àŽ†àŽšàŽżàŽźà”‡àŽ·à”» àŽžàŽ™à”àŽ™à”Ÿ àŽȘàŽ°àŽżàŽčàŽ°àŽżàŽšà”àŽšà”. àŽ’àŽ°à” àŽžà”àŽčà”ƒàŽ€à”àŽ€àŽżàŽšà”àŽ±à”† àŽźà”àŽ–àŽ‚ àŽ•àŽŸàŽŽà”àŽšàŽŻàŽżàŽČà”‡àŽ•à”àŽ•à” àŽžà”àŽČà”ˆàŽĄà” àŽšà”†àŽŻà”àŽŻà”àŽšà”àŽšàŽ€à” àŽ•àŽŸàŽŁà”àŽźà”àŽȘà”‹à”Ÿ, àŽ…àŽ€à”ŠàŽ°à” àŽžà”‹àŽ·à”àŽŻà”œ àŽźà”‚àŽ”à”àŽźà”†àŽšà”àŽ±àŽŸàŽŁà”." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àŽšàŽŸàŽ±à”àŽ±à” àŽ•à”àŽ°àŽźà”€àŽ•àŽ°àŽŁàŽ™à”àŽ™à”Ÿ àŽ”à”‡àŽ—àŽ€à”àŽ€àŽżà”œ àŽ†àŽ•à”â€ŒàŽžàŽžà” àŽšà”†àŽŻà”àŽŻàŽŸàŽšà”‹ àŽ† àŽšàŽŸàŽ±à”àŽ±àŽżà”œ àŽšàŽżàŽšà”àŽšà” àŽ•àŽŸàŽŁàŽŸàŽ€à”àŽ€ àŽžà”â€ŒàŽ±à”àŽ±à”‹àŽ±àŽżàŽ•à”Ÿ àŽ•àŽŸàŽŁàŽŸàŽšà”‹ àŽ‡àŽȘà”àŽȘà”‹à”Ÿ àŽšàŽŸàŽ±à”àŽ±à” àŽčà”†àŽĄàŽ±àŽżàŽČà”† àŽ’àŽ°à” àŽȘà”àŽ°à”ŠàŽ«à”ˆà”œ àŽ«à”‹àŽŸà”àŽŸà”‹àŽŻàŽżàŽČà”‹ àŽ—à”àŽ°à”‚àŽȘà”àŽȘà” àŽ…àŽ”àŽ€àŽŸàŽ±àŽżàŽČà”‹ àŽ•à”àŽČàŽżàŽ•à”àŽ•à” àŽšà”†àŽŻà”àŽŻàŽŸàŽ‚. àŽšàŽšà”àŽŠàŽż, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/mr-IN/messages.json b/_locales/mr-IN/messages.json index 31cd72b8e8..a61814546e 100644 --- a/_locales/mr-IN/messages.json +++ b/_locales/mr-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "à€Ąà„‡à€Ÿà€Ÿà€Źà„‡à€ž à€€à„à€°à„à€Ÿà„€", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "à€Ąà„‡à€Ÿà€Ÿà€Źà„‡à€ž à€€à„à€°à„à€Ÿà„€ à€‰à€Šà„à€­à€”à€Čà„€. à€†à€Șà€Ł à€€à„à€°à„à€Ÿà„€ à€•à„‰à€Șà„€ à€•à€°à„‚ à€†à€Łà€ż à€žà€źà€žà„à€Żà„‡à€šà„‡ à€šà€żà€°à€Ÿà€•à€°à€Ł à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ Signal à€žà€Șà„‹à€°à„à€Ÿà€¶à„€ à€źà€Šà€€à„€à€žà€Ÿà€ à„€ à€žà€‚à€Șà€°à„à€• à€•à€°à„‚ à€¶à€•à€€à€Ÿ. à€†à€Șà€Łà€Ÿà€Čà€Ÿ à€œà€° à€Čà€—à„‡à€šà€š Signal à€”à€Ÿà€Șà€°à€Łà„à€Żà€Ÿà€šà„€ à€—à€°à€œ à€…à€žà€Čà„à€Żà€Ÿà€ž, à€†à€Șà€Ł à€†à€Șà€Čà€Ÿ à€Ąà„‡à€Ÿà€Ÿ à€čà€Ÿà€”à„‚ à€¶à€•à€€à€Ÿ à€†à€Łà€ż à€Șà„à€šà„à€čà€Ÿ à€žà„à€°à„‚à€”à€Ÿà€€ à€•à€°à„‚ à€¶à€•à€€à€Ÿ.\n\n{link} :à€Čà€Ÿ à€­à„‡à€Ÿ à€Šà„‡à€Šà€š à€žà€Șà„‹à€°à„à€Ÿà€¶à„€ à€žà€‚à€Șà€°à„à€• à€žà€Ÿà€§à€Ÿ", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "à€žà€°à„à€” à€Ąà„‡à€Ÿà€Ÿ à€čà€Ÿà€”à€Ÿ à€†à€Łà€ż à€Șà„à€šà„à€čà€Ÿ à€žà„à€°à„‚ à€•à€°à€Ÿ", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "à€Ąà„‡à€Ÿà€Ÿ à€čà€Ÿà€”à€Ÿ à€†à€Łà€ż à€Șà„à€šà„à€čà€Ÿ à€žà„à€°à„‚ à€•à€°à€Ÿ", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "à€žà€°à„à€” à€Ąà„‡à€Ÿà€Ÿ à€•à€Ÿà€Żà€źà€žà„à€”à€°à„‚à€Șà„€ à€čà€Ÿà€”à€Ÿà€Żà€šà€Ÿ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€ž à€”à€°à„‚à€š à€†à€Șà€Čà„à€Żà€Ÿ à€žà€°à„à€” à€žà€‚à€Šà„‡à€¶à€Ÿà€‚à€šà€Ÿ à€‡à€€à€żà€čà€Ÿà€ž à€†à€Łà€ż à€źà€żà€Ąà„€à€Żà€Ÿ à€•à€Ÿà€Żà€źà€žà„à€”à€°à„‚à€Șà„€ à€čà€Ÿà€”à€Čà€Ÿ à€œà€Ÿà€ˆà€Č. à€†à€Șà€Ł à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€Čà€Ÿ à€Șà„à€šà„à€čà€Ÿ à€Čà€żà€‚à€• à€•à€°à„‚à€š à€€à„à€Żà€Ÿà€”à€° Signal à€”à€Ÿà€Șà€°à„‚ à€¶à€•à€Ÿà€Č. à€čà„‡ à€†à€Șà€Čà„à€Żà€Ÿ à€«à„‹à€šà€”à€°à„€à€Č à€•à„‹à€Łà€€à€Ÿà€čà„€ à€Ąà„‡à€Ÿà€Ÿ à€čà€Ÿà€”à€Łà€Ÿà€° à€šà€Ÿà€čà„€.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "à€†à€Șà€Čà„à€Żà€Ÿ à€Ąà„‡à€Ÿà€Ÿà€Źà„‡à€žà€šà„€ à€†à€”à„ƒà€€à„à€€à„€ à€Żà€Ÿ Signal à€šà„à€Żà€Ÿ à€†à€”à„ƒà€€à„à€€à„€ à€Źà€°à„‹à€Źà€° à€œà„à€łà€€ à€šà€Ÿà€čà„€. à€†à€Șà€Ł à€†à€Șà€Čà„à€Żà€Ÿ à€žà€‚à€—à€Łà€•à€Ÿà€”à€° Signal à€šà„€ à€šà€”à„€à€šà€€à€ź à€†à€”à„ƒà€€à„à€€à„€ à€‰à€˜à€Ąà€€ à€…à€žà€Čà„à€Żà€Ÿà€šà„€ à€–à€Ÿà€€à„à€°à„€ à€•à€°à€Ÿ.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "à€«à€Ÿà€ˆà€Č", @@ -300,6 +316,70 @@ "messageformat": "à€šà„…à€Ÿà„à€ž", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "à€†à€Șà€Čà„à€Żà€Ÿ à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€”à€Ÿà€žà€č à€•à€Ÿà€čà„€à€€à€°à„€ à€šà„à€•à„€à€šà„‡ à€à€Ÿà€Čà„‡ à€†à€čà„‡, à€€à„‡ à€Żà€Ÿà€Șà„à€ąà„‡ à€†à€Șà€Čà„à€Żà€Ÿ à€…à€•à€Ÿà€Šà€‚à€Ÿà€žà€č à€šà€żà€Żà„à€•à„à€€ à€•à„‡à€Čà„‡à€Čà„‡ à€šà€Ÿà€čà„€. à€†à€Șà€Ł à€Șà„à€°à€Żà€€à„à€š à€•à€°à„‚ à€¶à€•à€€à€Ÿ à€†à€Łà€ż à€€à„‹ à€Șà„à€šà„à€čà€Ÿ à€žà„‡à€Ÿ à€•à€°à„‚ à€¶à€•à€€à€Ÿ à€•à€żà€‚à€”à€Ÿ à€šà€”à„€à€š à€šà€żà€”à€Ąà„‚ à€¶à€•à€€à€Ÿ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "à€†à€€à„à€€à€Ÿ à€šà€żà€¶à„à€šà€żà€€ à€•à€°à€Ÿ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "à€†à€Șà€Čà„à€Żà€Ÿ QR à€•à„‹à€Ą à€†à€Łà€ż à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€Čà€żà€‚à€• à€žà€č à€•à€Ÿà€čà„€ à€€à€°à„€ à€šà„à€•à„€à€šà„‡ à€˜à€Ąà€Čà„‡ à€†à€čà„‡, à€€à„€ à€Żà€Ÿà€Șà„à€ąà„‡ à€”à„ˆà€§ à€šà€Ÿà€čà„€. à€‡à€€à€°à€Ÿà€‚à€žà€č à€¶à„‡à€…à€° à€•à€°à€Łà„à€Żà€Ÿà€ž à€à€• à€šà€”à„€à€š à€Čà€żà€‚à€• à€€à€Żà€Ÿà€° à€•à€°à€Ÿ.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "à€†à€€à„à€€à€Ÿ à€šà€żà€¶à„à€šà€żà€€ à€•à€°à€Ÿ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "à€Ÿà„…à€Źà„à€œ à€Šà€Ÿà€–à€”à€Ÿ", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "à€Ÿà„…à€Źà„à€œ à€Čà€Șà€”à€Ÿ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "à€à€• à€€à„à€°à„à€Ÿà„€ à€‰à€Šà„à€­à€”à€Čà„€", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} à€š à€”à€Ÿà€šà€Čà„‡à€Čà„‡", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "à€š à€”à€Ÿà€šà€Čà„‡à€Čà„‡ à€źà„à€čà€Łà„‚à€š à€šà€żà€šà„à€čà€żà€€", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "à€šà„…à€Ÿà„à€ž", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "à€•à„‰à€Č", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "à€žà„à€Ÿà„‹à€°à„€à€œ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "à€žà„‡à€Ÿà€żà€‚à€—", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal à€…à€Šà„à€Żà€€à€šà€żà€€ à€•à€°à€Ÿ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "à€Șà„à€°à„‹à€«à€Ÿà€ˆà€Č", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "à€źà€Ÿà€—à„‡", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "à€čà„‡ à€šà„…à€Ÿà„à€ž à€†à€°à„à€•à€Ÿà€ˆà€”à„à€čà„‡ à€•à„‡à€Čà„‡à€Čà„‡ à€†à€čà„‡à€€ à€†à€Łà€ż à€‡à€šà€Źà„‰à€•à„à€ž à€źà€§à„à€Żà„‡ à€«à€•à„à€€ à€šà€”à„€à€š à€žà€‚à€Šà„‡à€¶ à€Șà„à€°à€Ÿà€Șà„à€€ à€à€Ÿà€Čà„à€Żà€Ÿà€ž à€€à„‡ à€Šà€żà€žà€€à„€à€Č.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "à€€à€°à„€à€čà„€ à€•à„‰à€Č à€•à€°à€Ÿ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "à€•à€Ÿà€čà„€à€čà„€ à€•à€°à„‚à€š à€žà€Ÿà€źà„€à€Č à€”à„à€čà€Ÿ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "à€•à„‰à€Č à€žà„à€°à„‚ à€ à„‡à€”à€Ÿ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€• à€čà„‡ à€…à€Šà„à€Żà€€à€šà€żà€€ à€•à€°à€Łà„à€Żà€Ÿà€€ à€†à€Čà„‡ à€†à€čà„‡à€€.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "à€…à€§à€żà€• à€œà€Ÿà€Łà€Ÿ", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "à€źà€Ÿà€—à„€à€Č à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€•", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "à€Șà„à€ąà„€à€Č à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€•", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€• à€†à€”à„ƒà€€à„à€€à„€, {index,number} à€Șà„ˆà€•à„€ {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "à€žà€€à„à€Żà€Ÿà€Șà€żà€€ à€źà„à€čà€Łà„‚à€š à€šà€żà€šà„à€čà€Ÿà€‚à€•à€żà€€ à€•à€°à€Ÿ", @@ -663,33 +747,41 @@ "messageformat": "à€žà€€à„à€Żà€Ÿà€Șà€š à€žà€Ÿà€« à€•à€°à€Ÿ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} à€žà€č à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€šà€šà„€ à€Șà€Ąà€€à€Ÿà€łà€Łà„€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€, à€”à€°à„€à€Č à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€€à„à€Żà€Ÿà€‚à€šà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€žà€č à€€à„à€Čà€šà€Ÿ à€•à€°à€Ÿ. à€€à„‡ à€†à€Șà€Čà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€žà€č à€€à„à€źà€šà„à€Żà€Ÿ à€•à„‹à€Ąà€Čà€Ÿ à€žà„à€•à„…à€š à€Šà„‡à€–à„€à€Č à€•à€°à„‚ à€¶à€•à€€à€Ÿà€€.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "à€…à€§à€żà€• à€œà€Ÿà€Łà„‚à€š à€˜à„à€Żà€Ÿ", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} à€žà€č à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€šà€šà„€ à€Șà€Ąà€€à€Ÿà€łà€Łà„€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€, à€”à€°à„€à€Č à€°à€‚à€— à€•à€Ÿà€°à„à€Ą à€€à„à€Żà€Ÿà€‚à€šà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€žà€č à€œà„à€łà€”à€Ÿ à€†à€Łà€ż à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€€à„à€Čà€šà€Ÿ à€•à€°à€Ÿ. à€€à„‡ à€œà„à€łà€€ à€šà€žà€Čà„à€Żà€Ÿà€ž, à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€Šà„à€žà€°à„€ à€œà„‹à€Ąà„€ à€”à€Ÿà€Șà€°à„‚à€š à€Șà€čà€Ÿ. à€«à€•à„à€€ à€à€• à€œà„‹à€Ąà„€ à€œà„à€łà€”à€Łà„à€Żà€Ÿà€šà„€ à€—à€°à€œ à€†à€čà„‡.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} à€žà€č à€à€‚à€Ą-à€Ÿà„‚-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€šà€šà„€ à€Șà€Ąà€€à€Ÿà€łà€Łà„€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€, à€”à€°à„€à€Č à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€€à„à€Żà€Ÿà€‚à€šà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€žà€č à€€à„à€Čà€šà€Ÿ à€•à€°à€Ÿ. à€€à„‡ à€†à€Șà€Čà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€žà€č à€€à„à€źà€šà„à€Żà€Ÿ à€•à„‹à€Ąà€Čà€Ÿ à€žà„à€•à„…à€š à€Šà„‡à€–à„€à€Č à€•à€°à„‚ à€¶à€•à€€à€Ÿà€€.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€źà€§à„€à€Č à€Źà€Šà€Č", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal à€źà€§à„€à€Č à€Żà„‡à€Š à€˜à€Ÿà€€à€Čà„‡à€Čà„€ à€—à„‹à€Șà€šà„€à€Żà€€à€Ÿ à€”à„ˆà€¶à€żà€·à„à€Ÿà„à€Żà„‡ à€žà€•à„à€·à€ź à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€• à€čà„‡ à€žà€‚à€•à„à€°à€źà€Ł à€•à€Ÿà€Čà€Ÿà€”à€§à„€à€Šà€°à€źà„à€Żà€Ÿà€š à€…à€Šà„à€Żà€€à€šà€żà€€ à€•à„‡à€Čà„‡ à€œà€Ÿà€Łà€Ÿà€° à€†à€čà„‡à€€.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€Șà€Ąà€€à€Ÿà€łà€Łà„€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€, à€†à€Șà€Čà„à€Żà€Ÿ à€žà€‚à€Șà€°à„à€•à€Ÿà€‚à€šà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€ž à€žà€č à€°à€‚à€— à€•à€Ÿà€°à„à€Ą à€œà„à€łà€”à€Ÿ. à€€à„‡ à€œà„à€łà€€ à€šà€žà€Čà„à€Żà€Ÿà€ž, à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€Šà„à€žà€°à„€ à€œà„‹à€Ąà„€ à€”à€Ÿà€Șà€°à„‚à€š à€Șà€čà€Ÿ. à€«à€•à„à€€ à€à€• à€œà„‹à€Ąà„€ à€œà„à€łà€”à€Łà„à€Żà€Ÿà€šà„€ à€—à€°à€œ à€†à€čà„‡.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "à€źà€Šà€€ à€čà€”à„€?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "à€•à€łà€Čà„‡", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "à€†à€Șà€Ł à€œà„‡à€”à„à€čà€Ÿ à€Żà€Ÿ à€”à„à€Żà€•à„à€€à„€à€žà€č à€žà€‚à€Šà„‡à€¶à€Ÿà€‚à€šà„€ à€Šà„‡à€”à€Ÿà€Łà€˜à„‡à€”à€Ÿà€Ł à€•à€°à€Ÿà€Č à€€à„‡à€”à„à€čà€Ÿ à€€à„à€Żà€Ÿà€‚à€šà„à€Żà€Ÿà€žà€č à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€• à€€à€Żà€Ÿà€° à€•à„‡à€Čà„‡ à€œà€Ÿà€€à„€à€Č.", @@ -1267,10 +1359,6 @@ "messageformat": "à€…à€Čà„€à€•à€Ąà„€à€Č à€źà€żà€Ąà€żà€Żà€Ÿ à€Źà€˜à€Ÿ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} à€žà€č à€€à„à€źà€šà„à€Żà€Ÿ à€à€‚à€Ą-à€Ÿà„-à€à€‚à€Ą à€à€šà„à€•à„à€°à€żà€Șà„à€¶à€šà€šà„€ à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€žà€€à„à€Żà€Ÿà€Șà€żà€€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€, à€€à„à€Żà€Ÿà€‚à€šà„à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà€¶à„€ à€”à€°à„€à€Č à€•à„à€°à€źà€Ÿà€‚à€•à€Ÿà€‚à€šà„€ à€€à„à€Čà€šà€Ÿ à€•à€°à€Ÿ. à€€à„‡ à€”à€°à„€à€Č à€•à„à€Żà„‚à€†à€° à€•à„‹à€Ą à€Šà„‡à€–à„€à€Č à€žà„à€•à„…à€š à€•à€°à„‚ à€¶à€•à€€à€Ÿà€€.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "à€†à€Șà€Ł à€†à€€à€Ÿà€Șà€°à„à€Żà€‚à€€ à€Żà€Ÿ à€žà€‚à€Șà€°à„à€•à€Ÿà€žà„‹à€Źà€€ à€•à„à€ à€Čà€Ÿà€čà„€ à€žà€‚à€Šà„‡à€¶ à€”à€żà€šà€żà€źà€Ż à€•à„‡à€Čà„‡à€Čà€Ÿ à€šà€Ÿà€čà„€. à€€à„à€Żà€Ÿà€‚à€šà„à€Żà€Ÿà€žà„‹à€Źà€€à€šà€Ÿ à€†à€Șà€Čà€Ÿ à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€šà€‚à€Źà€° à€Șà€čà€żà€Čà„à€Żà€Ÿ à€žà€‚à€Šà„‡à€¶à€Ÿà€šà€‚à€€à€° à€‰à€Șà€Čà€Źà„à€§ à€čà„‹à€ˆà€Č." }, @@ -1334,17 +1422,17 @@ "messageformat": "à€źà€Ÿà€čà€żà€€à„€", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "à€čà€Ÿà€”à€Ÿ", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€čà€Ÿà€”à€Ÿ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "à€šà„…à€Ÿ à€čà€Ÿà€”à€Ÿà€Żà€šà„‡?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€čà€Ÿà€”à€Ÿà€Żà€šà€Ÿ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "à€čà„‡ à€šà„…à€Ÿ à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€ž à€”à€°à„‚à€š à€čà€Ÿà€”à€Čà„‡ à€œà€Ÿà€ˆà€Č.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "à€Żà€Ÿ à€šà„…à€Ÿà„à€žà€źà€§à„€à€Č à€žà€‚à€Šà„‡à€¶ à€Żà€Ÿ à€Ąà€żà€”à„à€čà€Ÿà€‡à€ž à€”à€°à„‚à€š à€čà€Ÿà€”à€Čà„‡ à€œà€Ÿà€€à„€à€Č. à€†à€Șà€Ł à€žà€‚à€Šà„‡à€¶ à€čà€Ÿà€”à€Čà„à€Żà€Ÿà€šà€‚à€€à€° à€Šà„‡à€–à„€à€Č à€…à€Šà„à€Żà€Ÿà€Ș à€čà„‡ à€šà„…à€Ÿà„à€ž à€¶à„‹à€§à„‚ à€¶à€•à€€à€Ÿ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "à€—à€Ÿ à€žà„‹à€Ąà€Ÿ", @@ -1438,6 +1526,14 @@ "messageformat": "à€Šà„‹à€šà„à€čà„€ à€šà„…à€Ÿà„à€žà€žà€Ÿà€ à„€à€šà€Ÿ à€†à€Șà€Čà€Ÿ à€žà€‚à€Šà„‡à€¶ à€‡à€€à€żà€čà€Ÿà€ž à€Żà„‡à€„à„‡ à€à€•à€€à„à€° à€•à€°à€Łà„à€Żà€Ÿà€€ à€†à€Čà€Ÿ à€†à€čà„‡.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} à€čà€Ÿ {conversationTitle} à€šà„à€Żà€Ÿ à€źà€Ÿà€Čà€•à„€à€šà€Ÿ à€†à€čà„‡. à€†à€Șà€Ł à€Šà„‹à€˜à„‡à€čà„€ {sharedGroup} à€šà„‡ à€žà€Šà€žà„à€Ż à€†à€čà€Ÿà€€.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} à€čà€Ÿ {conversationTitle} à€šà„à€Żà€Ÿ à€źà€Ÿà€Čà€•à„€à€šà€Ÿ à€†à€čà„‡", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "à€‰à€Šà„à€§à€°à€żà€€ à€žà€‚à€Šà„‡à€¶à€Ÿà€”à€°à„€à€Č à€šà€żà€€à„à€°à€Ÿà€šà„‡ à€„à€‚à€Źà€šà„‡à€Č", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "à€Șà„à€šà„à€čà€Ÿ à€•à„‰à€Č à€•à€°à€Ÿ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "à€•à„‰à€Č à€šà€Ÿà€Čà„‚ à€•à€°à€Ÿ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "à€•à„‰à€Čà€źà€§à„à€Żà„‡ à€žà€Ÿà€źà„€à€Č à€”à„à€čà€Ÿ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "à€•à„‰à€Čà€šà„à€Żà€Ÿ à€•à€Ÿà€Čà€Ÿà€”à€§à„€à€źà„à€łà„‡ à€źà€Ÿà€Żà€•à„à€°à„‹à€«à„‹à€š à€źà„‚à€• à€•à€°à€Łà„à€Żà€Ÿà€€ à€†à€Čà„‡à€Čà€Ÿ à€†à€čà„‡", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "à€•à„‰à€Č à€…à€§à€żà€žà„‚à€šà€šà€Ÿ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "à€•à„‰à€Č à€Șà„‚à€°à„à€Ł à€†à€čà„‡", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "à€•à„…à€źà„‡à€°à€Ÿ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "à€žà€Ÿà€źà„€à€Č à€”à„à€čà€Ÿ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "à€šà€Ÿà€Čà„‚ à€•à€°à€Ÿ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "à€•à„‰à€Č à€«à„à€Čà„à€Č à€†à€čà„‡", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "à€•à„…à€źà„‡à€°à€Ÿ à€…à€•à„à€·à€ź à€•à„‡à€Čà„‡", @@ -1621,10 +1725,6 @@ "messageformat": "à€•à„…à€źà„‡à€°à€Ÿ à€šà€Ÿà€Čà„‚ à€•à€°à€Ÿ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "à€źà„‚à€• à€•à€°à€Ÿ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "à€źà€Ÿà€Żà€•à„à€°à„‹à€«à„‹à€š à€…à€•à„à€·à€ź à€•à„‡à€Čà„‡", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "à€źà€Ÿà€ˆà€• à€…à€šà€źà„à€Żà„‚à€Ÿ à€•à€°à€Ÿ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "à€žà€Ÿà€źà€Ÿà€Żà€żà€• à€•à€°à€Ÿ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "à€žà€Ÿà€Šà€° à€•à€°à€Łà„‡ à€…à€•à„à€·à€ź à€•à„‡à€Čà„‡ à€—à„‡à€Čà„‡", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "à€žà€Ÿà€Šà€° à€•à€°à€Łà„‡ à€Źà€‚à€Š à€•à€°à€Ÿ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "à€°à€żà€‚à€—", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "à€žà€čà€­à€Ÿà€—à„€à€‚à€šà€Ÿ à€°à€żà€‚à€— à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€čà€Ÿ à€—à€Ÿ à€–à„‚à€Ș à€źà„‹à€ à€Ÿ à€†à€čà„‡.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "à€°à€żà€‚à€—à€żà€‚à€— à€žà€•à„à€·à€ź à€•à€°à€Ÿ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "à€°à€żà€‚à€— à€čà„‹à€Łà„‡ à€Źà€‚à€Š à€•à€°à€Ÿ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "à€°à€żà€‚à€— à€čà„‹à€Łà„‡ à€žà„à€°à„‚ à€•à€°à€Ÿ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "à€…à€§à€żà€• à€Șà€°à„à€Żà€Ÿà€Ż", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "à€†à€Șà€Ł", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "à€†à€Șà€Čà€Ÿ à€•à„…à€źà„‡à€°à€Ÿ à€Źà€‚à€Š à€†à€čà„‡", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€• à€Șà€čà€Ÿ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "à€žà€‚à€Šà„‡à€¶", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "à€žà„à€°à€•à„à€·à€żà€€à€€à€Ÿ à€•à„à€°à€źà€Ÿà€‚à€• à€Șà€čà€Ÿ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "à€«à„‹à€š à€šà€‚à€Źà€° à€“à€ąà„‚à€š à€•à€Ÿà€ąà€Łà„à€Żà€Ÿà€€ à€…à€Żà€¶à€žà„à€”à„€. à€†à€Șà€Čà„‡ à€•à€šà„‡à€•à„à€¶à€š à€€à€Șà€Ÿà€žà€Ÿ à€†à€Łà€ż à€Șà„à€šà„à€čà€Ÿ à€Șà„à€°à€Żà€€à„à€š à€•à€°à€Ÿ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "à€†à€Șà€Ł à€čà€Ÿ à€žà€‚à€Šà„‡à€¶ à€Șà€Ÿà€ à€”à€Čà„à€Żà€Ÿà€Șà€Ÿà€žà„‚à€š à€«à€•à„à€€ 3 à€€à€Ÿà€žà€Ÿà€‚à€šà„à€Żà€Ÿ à€†à€€ à€žà€‚à€Șà€Ÿà€Šà€š à€•à€°à€Łà„‡ à€Čà€Ÿà€—à„‚ à€•à„‡à€Čà„‡ à€œà€Ÿà€Š à€¶à€•à€€à„‡.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "à€†à€Șà€Ł à€čà€Ÿ à€žà€‚à€Šà„‡à€¶ à€Șà€Ÿà€ à€”à€Čà„à€Żà€Ÿà€Șà€Ÿà€žà„‚à€š à€«à€•à„à€€ 24 à€€à€Ÿà€žà€Ÿà€‚à€šà„à€Żà€Ÿ à€†à€€ à€žà€‚à€Șà€Ÿà€Šà€š à€•à€°à€Łà„‡ à€Čà€Ÿà€—à„‚ à€•à„‡à€Čà„‡ à€œà€Ÿà€Š à€¶à€•à€€à„‡.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "à€čà€Ÿ à€žà€‚à€Šà„‡à€¶ à€čà€Ÿà€”à€żà€Čà€Ÿ à€—à„‡à€Čà€Ÿ à€čà„‹à€€à€Ÿ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "à€Șà„à€°à€Šà€°à„à€¶à€żà€€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€žà€‚à€Čà€—à„à€šà€• à€«à€Ÿà€° à€źà„‹à€ à€Ÿ à€†à€čà„‡.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "à€•à€Ÿà€čà„€ à€žà€‚à€Čà€—à„à€šà€•à„‡ à€Șà„à€°à€Šà€°à„à€¶à€żà€€ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€…à€€à€żà€¶à€Ż à€źà„‹à€ à„à€Żà€Ÿ à€†à€čà„‡à€€.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "à€Šà„‡à€Łà€—à„€ à€€à€Șà€¶à„€à€Č à€•à€Ÿà€ąà€Łà„à€Żà€Ÿà€€ à€…à€•à„à€·à€ź", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "à€«à€•à„à€€ Signal à€Źà„€à€Ÿà€Ÿ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€š à€•à€°à€Łà„‡ à€čà„‡ à€«à€•à„à€€ Signal à€Źà„€à€Ÿà€Ÿ à€”à€Ÿà€Șà€°à€•à€°à„à€€à„à€Żà€Ÿà€žà€Ÿà€ à„€ à€‰à€Șà€Čà€Źà„à€§ à€†à€čà„‡. à€†à€Șà€Ł à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à„‡à€Čà„à€Żà€Ÿà€ž, à€€à„‹ à€œà„‡ à€Čà„‹à€• Signal à€Źà„€à€Ÿà€Ÿà€šà„à€Żà€Ÿ à€šà€”à„€à€šà€€à€ź à€†à€”à„ƒà€€à„à€€à„€à€”à€° à€†à€čà„‡à€€ à€«à€•à„à€€ à€€à„à€Żà€Ÿà€‚à€šà€Ÿà€š à€Šà„ƒà€¶à„à€Żà€źà€Ÿà€š à€…à€žà„‡à€Č.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à€°à€Ÿ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "à€†à€Șà€Ł à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à„‡à€Čà„à€Żà€Ÿà€ž, à€€à„‹ Signal à€šà„à€Żà€Ÿ à€šà€”à„€à€šà€€à€ź à€†à€”à„ƒà€€à„à€€à„€à€”à€° à€…à€žà€Čà„‡à€Čà„à€Żà€Ÿ à€Čà„‹à€•à€Ÿà€‚à€šà€Ÿà€š à€Šà„ƒà€¶à„à€Żà€źà€Ÿà€š à€…à€žà„‡à€Č. à€€à„‡ à€†à€Șà€Čà€Ÿ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à„‡à€Čà„‡à€Čà€Ÿ à€žà€‚à€Šà„‡à€¶ à€Șà€Ÿà€čà„‚ à€¶à€•à€€à„€à€Č.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "à€Żà„‡à€Łà€Ÿà€°à€Ÿ à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "à€Źà€Ÿà€čà„‡à€° à€œà€Ÿà€Łà€Ÿà€°à€Ÿ à€”à„à€čà€Ÿà€ˆà€ž à€•à„‰à€Č", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "à€œà€Ÿà€Łà€Ÿà€°à€Ÿ à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} à€€à„à€źà„à€čà€Ÿà€Čà€Ÿ à€•à„‰à€Č à€•à€°à€€ à€†à€čà„‡", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "à€Șà„à€šà„à€čà€Ÿ à€•à€šà„‡à€•à„à€Ÿ à€•à€°à€€ à€†à€čà„‡(...)", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} à€”à„à€Żà€•à„à€€à€ż} other {{count,number} à€Čà„‹à€•}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "à€‘à€Ąà€żà€“ à€•à„‰à€Č", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "à€žà€źà€Ÿà€Șà„à€€", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "à€žà„‹à€Ąà€Ÿ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "à€źà€Ÿà€ˆà€• à€Źà€‚à€Š à€†à€čà„‡", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "à€źà€Ÿà€ˆà€• à€šà€Ÿà€Čà„‚ à€†à€čà„‡", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "à€°à€żà€‚à€— à€čà„‹à€Łà„‡ à€žà„à€°à„‚ à€à€Ÿà€Čà„‡", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "à€°à€żà€‚à€— à€čà„‹à€Łà„‡ à€Źà€‚à€Š à€à€Ÿà€Čà„‡", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "à€žà„‡à€Ÿà€żà€‚à€—", @@ -3468,13 +3668,25 @@ "messageformat": "à€•à„‰à€Č à€Șà„‚à€°à„à€Łà€žà„à€•à„à€°à„€à€š à€•à€°à€Ÿ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "à€—à„à€°à„€à€Ą à€Šà„ƒà€¶à„à€Żà€Ÿà€”à€° à€žà„à€”à€żà€š à€•à€°à€Ÿ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "à€Šà„ƒà€¶à„à€Ż à€Źà€Šà€Čà€Ÿ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "à€žà„à€Șà„€à€•à€° à€Šà„ƒà€¶à„à€Żà€Ÿà€”à€° à€žà„à€”à€żà€š à€•à€°à€Ÿ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "à€—à„à€°à€żà€Ą à€Šà„ƒà€¶à„à€Ż", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "à€žà€Ÿà€‡à€Œà€Ąà€Źà€Ÿà€° à€Šà„ƒà€¶à„à€Ż", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "à€”à€•à„à€€à€Ÿ à€Šà„ƒà€¶à„à€Ż", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "à€Šà„ƒà€¶à„à€Ż à€…à€Šà„à€Żà€€à€šà€żà€€ à€•à„‡à€Čà„‡", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "à€•à„‰à€Č à€žà„‹à€Ąà€Ÿ", @@ -3576,6 +3788,14 @@ "messageformat": "à€ à„€à€• à€†à€čà„‡", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "à€žà€‚à€Šà„‡à€¶ à€žà€‚à€Șà€Ÿà€Šà€żà€€ à€•à€°à„‚ à€¶à€•à€€ à€šà€Ÿà€čà„€", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "à€Żà€Ÿ à€žà€‚à€Šà„‡à€¶à€Ÿà€Čà€Ÿ à€«à€•à„à€€ {max,number} à€žà€‚à€Șà€Ÿà€Šà€šà„‡ à€Čà€Ÿà€—à„‚ à€•à„‡à€Čà„€ à€œà€Ÿà€Š à€¶à€•à€€à€Ÿà€€.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "à€•à„à€·à€źà€žà„à€”, à€€à„à€Żà€Ÿ sgnl:// à€Šà„à€”à€Ÿà€šà€Ÿ à€•à€Ÿà€čà„€ à€…à€°à„à€„ à€šà€żà€˜à€Ÿà€Čà€Ÿ à€šà€Ÿà€čà„€!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿà€šà€Ÿà€”", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "à€†à€Șà€Čà„à€Żà€Ÿ à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€”à€Ÿà€žà€č à€•à€Ÿà€čà„€à€€à€°à„€ à€šà„à€•à„€à€šà„‡ à€à€Ÿà€Čà„‡ à€†à€čà„‡, à€€à„‡ à€Żà€Ÿà€Șà„à€ąà„‡ à€†à€Șà€Čà„à€Żà€Ÿ à€…à€•à€Ÿà€Šà€‚à€Ÿà€žà€č à€šà€żà€Żà„à€•à„à€€ à€•à„‡à€Čà„‡à€Čà„‡ à€šà€Ÿà€čà„€.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€” à€čà€Ÿà€”à€Ÿ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿà€šà€Ÿà€” à€€à€Żà€Ÿà€° à€•à€°à€Ÿ", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR à€•à„‹à€Ą à€•à€żà€‚à€”à€Ÿ à€Čà€żà€‚à€•", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€” à€°à„€à€žà„‡à€Ÿ à€•à€°à€Łà„à€Żà€Ÿà€šà„€ à€—à€°à€œ à€†à€čà„‡", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€Čà€żà€‚à€• à€°à„€à€žà„‡à€Ÿ à€•à€°à€Łà„à€Żà€Ÿà€šà„€ à€—à€°à€œ à€†à€čà„‡", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "à€†à€Șà€Čà„‡ à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€” à€¶à„‡à€…à€° à€•à€°à€Ÿ", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€” à€čà€Ÿà€”à€Ÿ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "à€čà„‡ à€€à„à€źà€šà„‡ à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€” à€•à€Ÿà€ąà„‚à€š à€Ÿà€Ÿà€•à„‡à€Č, à€‡à€€à€° à€”à€Ÿà€Șà€°à€•à€°à„à€€à„à€Żà€Ÿà€‚à€šà€Ÿ à€€à„à€Żà€Ÿà€”à€° à€Šà€Ÿà€”à€Ÿ à€•à€°à€€à€Ÿ à€Żà„‡à€ˆà€Č. à€€à„à€źà€šà„€ à€–à€Ÿà€€à„à€°à„€ à€†à€čà„‡ à€•à€Ÿ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "à€čà„‡ à€†à€Șà€Čà„‡ à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€šà€Ÿà€” à€čà€Ÿà€”à„‡à€Č à€†à€Łà€ż à€†à€Șà€Čà€Ÿ QR à€•à„‹à€Ą à€†à€Łà€ż à€Čà€żà€‚à€• à€…à€•à„à€·à€ź à€•à€°à„‡à€Č. “{username}” à€‡à€€à€°à€Ÿà€‚à€šà€Ÿ à€Šà€Ÿà€”à€Ÿ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€‰à€Șà€Čà€Źà„à€§ à€…à€žà„‡à€Č. à€€à„à€źà„à€čà€Ÿà€Čà€Ÿ à€–à€Ÿà€€à„à€°à„€ à€†à€čà„‡?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "à€†à€Șà€Ł à€Żà€Ÿà€Șà„à€ąà„‡ à€žà„à€Ÿà„‹à€°à„€à€œ à€¶à„‡à€…à€° à€•à€°à„‚ à€•à€żà€‚à€”à€Ÿ à€Șà€Ÿà€čà„‚ à€¶à€•à€Łà€Ÿà€° à€šà€Ÿà€čà„€. à€†à€Șà€Ł à€…à€Čà€żà€•à€Ąà„‡à€š à€¶à„‡à€…à€° à€•à„‡à€Čà„‡à€Čà„€ à€žà„à€Ÿà„‹à€°à„€à€œ à€…à€Šà„à€Żà€€à€šà„‡ à€Šà„‡à€–à„€à€Č à€čà€Ÿà€”à€Čà„€ à€œà€Ÿà€€à„€à€Č.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "à€­à€Ÿà€·à€Ÿ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "à€­à€Ÿà€·à€Ÿ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "à€žà€żà€žà„à€Ÿà€żà€ź à€­à€Ÿà€·à€Ÿ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "à€­à€Ÿà€·à€Ÿ à€¶à„‹à€§à€Ÿ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” à€žà€Ÿà€ à„€ à€•à„‹à€Łà€€à„‡à€čà„€ à€Șà€°à€żà€Łà€Ÿà€ź à€šà€Ÿà€čà„€à€€", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "à€žà„‡à€Ÿ à€•à€°à€Ÿ", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "à€Čà€Ÿà€—à„‚ à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ Signal à€Șà„à€šà„à€čà€Ÿ à€žà„à€°à„ à€•à€°à€Ÿ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "à€­à€Ÿà€·à€Ÿ à€Źà€Šà€Čà€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€, à„Čà€Ș à€Șà„à€šà„à€čà€Ÿ à€žà„à€°à„ à€•à€°à€Łà„à€Żà€Ÿà€šà„€ à€—à€°à€œ à€†à€čà„‡.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "à€Șà„à€šà„à€čà€Ÿ à€žà„à€°à„ à€•à€°à€Ÿ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} à€”à€° à€…à€Șà€Ąà„‡à€Ÿ à€†à€”à„ƒà€€à„€ à€‰à€Șà€Čà€Źà„à€§ à€†à€čà„‡", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "à€€à„à€źà€šà„€ à€žà„‡à€”à„à€čà€żà€‚à€—à„à€œ à€žà„‡à€”à„à€č à€•à€°à€€à€Ÿà€‚à€šà€Ÿ à€€à„à€°à„à€Ÿà„€ à€†à€Čà„€. à€•à„ƒà€Șà€Żà€Ÿ à€Șà„à€šà„à€čà€Ÿ à€Șà„à€°à€Żà€€à„à€š à€•à€°à€Ÿ.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "à€žà€‚à€Šà„‡à€¶", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "à€…à€§à€żà€• à€¶à„ˆà€Čà„€", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "à€°à„€à€žà„‡à€Ÿ à€•à€°à€Ÿ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "à€ à„€à€•", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿ à€Čà€żà€‚à€• à€°à€‚à€—, {index,number} à€Șà„ˆà€•à„€ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "à€†à€Șà€Ł à€†à€Șà€Čà€Ÿ QR à€•à„‹à€Ą à€°à„€à€žà„‡à€Ÿ à€•à„‡à€Čà„à€Żà€Ÿà€ž, à€†à€Șà€Čà€Ÿ à€…à€žà„à€€à€żà€€à„à€”à€Ÿà€€ à€…à€žà€Čà„‡à€Čà€Ÿ QR à€•à„‹à€Ą à€†à€Łà€ż à€Čà€żà€‚à€• à€Żà€Ÿà€Șà„à€ąà„‡ à€•à€Ÿà€ź à€•à€°à€Łà€Ÿà€° à€šà€Ÿà€čà„€.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "à€Čà€żà€‚à€• à€°à„€à€žà„‡à€Ÿ à€•à€°à€€ à€†à€čà„‡...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR à€•à„‹à€Ą à€†à€Łà€ż à€Čà€żà€‚à€• à€žà„‡à€Ÿ à€•à„‡à€Čà„‡à€Čà„€ à€šà€Ÿà€čà„€. à€†à€Șà€Čà„‡ à€šà„‡à€Ÿà€”à€°à„à€• à€•à€šà„‡à€•à„à€¶à€š à€€à€Șà€Ÿà€žà€Ÿ à€†à€Łà€ż à€Șà„à€šà„à€čà€Ÿ à€Șà„à€°à€Żà€€à„à€š à€•à€°à€Ÿ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "à€†à€Șà€Čà„‡ Signal à€”à€Ÿà€Șà€°à€•à€°à„à€€à€Ÿà€šà€Ÿà€” à€žà„‡à€Ÿà€…à€Ș à€•à€°à€Ÿ", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "à€Șà„à€šà„à€čà€Ÿ à€Șà€Ÿà€ à€”à€Ÿ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "à€…à€§à€żà€• à€•à„à€°à€żà€Żà€Ÿ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "à€•à„‰à€Č", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "à€šà€”à„€à€š à€•à„‰à€Č", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "à€šà€”à„€à€š à€•à„‰à€Č", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "à€…à€§à€żà€• à€•à„à€°à€żà€Żà€Ÿ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà€Ÿà€« à€•à€°à€Ÿ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà€Ÿà€« à€•à€°à€Ÿà€Żà€šà€Ÿ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "à€čà„‡ à€•à€Ÿà€Żà€źà€žà„à€”à€°à„‚à€Șà„€ à€žà€°à„à€” à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€čà€Ÿà€”à„‡à€Č", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "à€žà€Ÿà€« à€•à€°à€Ÿ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "à€•à„‰à€Č à€‡à€€à€żà€čà€Ÿà€ž à€žà€Ÿà€« à€•à„‡à€Čà€Ÿ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "à€Șà€Ÿà€čà€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€•à€żà€‚à€”à€Ÿ à€•à„‰à€Č à€žà„à€°à„‚ à€•à€°à€Łà„à€Żà€Ÿà€ž à€•à„à€Čà€żà€• à€•à€°à€Ÿ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "à€¶à„‹à€§", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "à€źà€żà€žà„à€Ą à€à€Ÿà€Čà„‡à€Čà„à€Żà€Ÿà€šà„à€žà€Ÿà€° à€«à€żà€Čà„à€Ÿà€° à€•à€°à€Ÿ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "à€Ÿà„‰à€—à€Č à€•à€°à€Ÿ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "à€•à„‹à€Łà€€à„‡à€čà„€ à€…à€Čà€żà€•à€Ąà„€à€Č à€•à„‰à€Č à€šà€Ÿà€čà„€à€€. à€źà€żà€€à„à€°à€Ÿà€Čà€Ÿ à€•à„‰à€Č à€•à€°à„à€š à€žà„à€°à„à€”à€Ÿà€€ à€•à€°à€Ÿ.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” à€žà€Ÿà€ à„€ à€•à„‹à€Łà€€à„‡à€čà„€ à€Șà€°à€żà€Łà€Ÿà€ź à€šà€Ÿà€čà„€à€€", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "à€Żà„‡à€Łà€Ÿà€°à„‡", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "à€Źà€Ÿà€čà„‡à€° à€œà€Ÿà€Łà€Ÿà€°à„‡", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "à€źà€żà€žà„à€Ą", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "à€—à€Ÿ à€•à„‰à€Č", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "à€•à„‹à€Łà€€à„‡à€čà„€ à€…à€Čà€żà€•à€Ąà„€à€Č à€žà€‚à€­à€Ÿà€·à€Ł à€šà€Ÿà€čà„€.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” à€žà€Ÿà€ à„€ à€•à„‹à€Łà€€à„‡à€čà„€ à€Șà€°à€żà€Łà€Ÿà€ź à€šà€Ÿà€čà„€à€€", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {à€Źà€Ÿà€čà„‡à€° à€œà€Ÿà€Łà€Ÿà€°à€Ÿ à€”à„à€čà€Ÿà€ˆà€ž à€•à„‰à€Č} other {à€Żà„‡à€Łà€Ÿà€°à€Ÿ à€”à„à€čà€Ÿà€ˆà€ž à€•à„‰à€Č}}} Video {{direction, select, Outgoing {à€œà€Ÿà€Łà€Ÿà€°à€Ÿ à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č} other {à€Żà„‡à€Łà€Ÿà€°à€Ÿ à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č}}} Group {{direction, select, Outgoing {à€Źà€Ÿà€čà„‡à€° à€œà€Ÿà€Łà€Ÿà€°à„‡ à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€Żà„‡à€Łà€Ÿà€°à„‡ à€—à„à€°à„à€Ș à€•à„‰à€Č}}} other {{direction, select, Outgoing {à€œà€Ÿà€Łà€Ÿà€°à€Ÿ à€•à„‰à€Č} other {à€Żà„‡à€Łà€Ÿà€°à€Ÿ à€•à„‰à€Č}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {à€šà„‚à€•à€”à€Čà„‡à€Čà€Ÿ à€”à„à€čà€Ÿà€ˆà€ž à€•à„‰à€Č} Video {à€žà„à€Ÿà€Čà„‡à€Čà€Ÿ à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č} Group {à€šà„à€•à€Čà„‡à€Čà„‡ à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€žà„à€Ÿà€Čà„‡à€Čà€Ÿ à€•à„‰à€Č}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {à€…à€šà„à€€à„à€€à€°à€żà€€ à€”à„à€čà„‰à€ˆà€ž à€•à„‰à€Č} Video {à€…à€šà„à€€à„à€€à€°à€żà€€ à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č} Group {à€‰à€€à„à€€à€° à€š à€Šà€żà€Čà„‡à€Čà€Ÿ à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€‰à€€à„à€€à€° à€š à€Šà€żà€Čà„‡à€Čà€Ÿ à€•à„‰à€Č}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {à€”à„à€čà„‰à€ˆà€ž à€•à„‰à€Č à€šà€Ÿà€•à€Ÿà€°à€Ÿ} Video {à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č à€šà€Ÿà€•à€Ÿà€°à€Ÿ} Group {à€šà€Ÿà€•à€Ÿà€°à€Čà„‡à€Čà€Ÿ à€—à„à€°à„à€Ș à€•à„‰à€Č} other {à€šà€Ÿà€•à€Ÿà€°à€Čà„‡à€Čà€Ÿ à€•à„‰à€Č}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} à€‡à€€à€° à€Ÿà€Ÿà€ˆà€Ș à€•à€°à€€ à€†à€čà„‡.} other {{count,number} à€‡à€€à€° à€Ÿà€Ÿà€ˆà€Ș à€•à€°à€€ à€†à€čà„‡à€€.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "à€šà€”à„€à€š à€•à€Ÿà€Ż à€†à€čà„‡", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "à€Čà€čà€Ÿà€š à€Ÿà„à€”à€żà€•à„à€ž, à€Šà„‹à€· à€šà€żà€”à€Ÿà€°à€Ł, à€†à€Łà€ż à€•à€Ÿà€źà€—à€żà€°à„€ à€žà„à€§à€Ÿà€°à€Łà€Ÿ. Signal à€”à€Ÿà€Șà€°à€Čà„à€Żà€Ÿà€Źà€Šà„à€Šà€Č à€†à€­à€Ÿà€°à„€ à€†à€čà„‹à€€!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "à€Żà€Ÿ à€…à€Šà„à€Żà€€à€šà€Ÿà€źà€§à„à€Żà„‡ à€”à„à€čà€Ÿà€ˆà€ž à€†à€Łà€ż à€”à„à€čà€żà€Ąà€żà€“ à€•à„‰à€Č à€Żà€Ÿà€‚à€šà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€•à€Ÿà€čà„€ à€žà„à€§à€Ÿà€°à€Łà€Ÿ, à€†à€Łà€ż à€•à€Ÿà€čà„€ à€Čà€čà€Ÿà€š à€Šà€žà„à€€à€à€”à€œà„€à€•à€°à€Ł à€…à€Šà„à€Żà€€à€šà€Ÿà€‚à€šà€Ÿ à€žà€źà€Ÿà€”à„‡à€¶ à€†à€čà„‡ (à€§à€šà„à€Żà€”à€Ÿà€Š, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "à€†à€€à€Ÿ à€†à€Șà€Ł Signal à€źà€§à„à€Żà„‡ à€†à€Șà€Čà„€ à€šà€żà€”à€Ąà€Čà„‡à€Čà„€ à€­à€Ÿà€·à€Ÿ à€†à€Șà€Čà„‡ à€žà€żà€žà„à€Ÿà€żà€‚à€ź à€žà„‡à€Ÿà€żà€‚à€—à„à€œ à€š à€Źà€Šà€Čà€€à€Ÿ à€Źà€Šà€Čà„‚ à€¶à€•à€€à€Ÿ (Signal à€žà„‡à€Ÿà€żà€‚à€—à„à€œ > à€žà„à€”à€°à„‚à€Ș > à€­à€Ÿà€·à€Ÿ)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "à€†à€źà„à€čà„€ à€—à€Ÿ à€…à€Šà„à€Żà€€à€šà€Ÿà€‚à€žà€Ÿà€ à„€ à€Šà€żà€žà€Łà€Ÿà€°à„€ à€…à€§à€żà€žà„‚à€šà€šà€Ÿ à€šà€żà€šà„à€čà„‡ à€…à€Šà„à€Żà€Żà€Ÿà€”à€€ à€•à„‡à€Čà„€ à€†à€čà„‡à€€, à€œà€žà„‡ à€œà„‡à€”à„à€čà€Ÿ à€•à„‹à€Łà„€à€€à€°à„€ à€šà€”à„€à€š à€—à€Ÿà€Ÿà€źà€§à„à€Żà„‡ à€žà€Ÿà€źà„€à€Č à€čà„‹à€€à„‡. à€”à€żà€¶à„‡à€·à€€: à€€à„à€źà„à€čà„€ à€—à€Ąà€Š à€„à„€à€źà€šà„à€Żà€Ÿ à€—à€Ąà€Šà€Șà€Łà€Ÿà€šà„à€Żà€Ÿ à€†à€€ à€œà€—à€€ à€…à€žà€Ÿà€Č à€€à€°, à€čà„€ à€šà€żà€šà„à€čà„‡ à€žà„à€”à€Ÿà€šà„à€Żà€€à€Ÿ, à€žà„à€§à€Ÿà€°à€Łà„à€Żà€Ÿà€ž à€źà€Šà€€ à€•à€°à€€à„€à€Č. à€Șà„‚à€°à„à€”à„€à€šà„€ à€šà€żà€šà„à€čà„‡ à€•à„‡à€”à€ł à€—à€Ąà€Šà€Șà€Łà€Ÿà€Čà€Ÿ à€žà„à€”à„€à€•à€Ÿà€°à€€ à€čà„‹à€€à„€. à€šà€”à„€à€š à€†à€Żà€•à„‰à€š à€€à„à€Żà€Ÿà€€à„‚à€š à€œà€šà„à€źà€Čà„‡ à€†à€čà„‡à€€, à€€à„à€Żà€Ÿà€šà„‡ à€źà„‹à€Čà„à€Ą à€•à„‡à€Čà„‡à€Čà„‡ à€†à€čà„‡à€€." + "icu:WhatsNew__v6.39--1": { + "messageformat": "à€†à€źà„à€čà„€ macOS à€Ąà€żà€”à„à€čà€Ÿà€‡à€žà„‡à€žà€”à€° à€•à„‰à€Č à€Čà„‰à€Źà„€ à€œà„‰à€ˆà€š à€•à€°à€€à€Ÿà€šà€Ÿ à€•à€Ÿà€čà„€ à€”à„‡à€łà€Ÿ à€‰à€Šà„à€­à€”à€Łà€Ÿà€±à„à€Żà€Ÿ à€„à„‹à€Ąà„à€Żà€Ÿ à€”à€żà€Čà€‚à€Źà€Ÿà€Čà€Ÿ à€Šà„à€°à„‚à€žà„à€€ à€•à„‡à€Čà„‡ à€†à€čà„‡, à€œà„à€Żà€Ÿà€źà„à€łà„‡ à€Źà„ˆà€ à€•à„€à€Čà€Ÿ à€čà„‹à€Łà€Ÿà€°à€Ÿ à€…à€°à„à€§à„à€Żà€Ÿ-à€žà„‡à€•à€‚à€Šà€Ÿà€šà„à€Żà€Ÿ à€”à€żà€Čà€‚à€Źà€Ÿà€šà„à€Żà€Ÿ à€à€•à€Ÿ à€•à€Ÿà€°à€Łà€Ÿà€Șà€Ÿà€žà„‚à€š à€žà„à€Ÿà€•à€Ÿ à€Šà„‡à€ˆà€Č." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "à€œà„‡à€”à„à€čà€Ÿ à€•à„‹à€Łà„€à€€à€°à„€ à€žà€źà„‚à€č à€•à„‰à€Č à€źà€§à„à€Żà„‡ à€œà„‹à€Ąà€Čà€Ÿ à€œà€Ÿà€€à„‹ à€•à€żà€‚à€”à€Ÿ à€žà€źà„‚à€č à€•à„‰à€Čà€Čà€Ÿ à€žà„‹à€Ąà€€à„‹ à€€à„‡à€”à„à€čà€Ÿ à€”à„à€čà€żà€Ąà€żà€“ à€Ÿà€Ÿà€‡à€Čà„à€žà€žà€Ÿà€ à„€ à€Șà€°à€żà€”à€°à„à€€à€š à€…â€à„…à€šà€żà€źà„‡à€¶à€š à€Šà„à€°à„‚à€žà„à€€ à€•à„‡à€Čà„‡ à€†à€čà„‡. à€œà„‡à€”à„à€čà€Ÿ à€†à€Șà€Łà€Ÿà€Čà€Ÿ à€źà€żà€€à„à€°à€Ÿà€šà€Ÿ à€šà„‡à€čà€°à€Ÿ à€Šà„ƒà€¶à„à€Ż à€źà€§à„à€Żà„‡ à€Šà€żà€žà„‡à€Č, à€€à„€ à€à€• à€žà€Ÿà€źà€Ÿà€œà€żà€• à€čà€Ÿà€Čà€šà€Ÿà€Č à€…à€žà„‡à€Č." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "à€†à€€à€Ÿ à€†à€Șà€Ł à€šà„…à€Ÿà„à€ž à€¶à€żà€°à„à€·à€•à€Ÿà€źà€˜à„€à€Č à€Șà„à€°à„‹à€«à€Ÿà€‡à€Č à€«à„‹à€Ÿà„‹ à€•à€żà€‚à€”à€Ÿ à€žà€źà„‚à€č à€…à€”à€€à€Ÿà€° à€Żà€Ÿà€”à€° à€€à„à€Żà€Ÿ à€šà„…à€Ÿà€źà€§à„€à€Č à€•à„‹à€Łà€€à„à€Żà€Ÿà€čà„€ à€š à€Șà€Ÿà€čà€żà€Čà„‡à€Čà„à€Żà€Ÿ à€žà„à€Ÿà„‹à€°à„€à€œ à€•à€żà€‚à€”à€Ÿ à€šà„…à€Ÿà„à€ž à€žà„‡à€Ÿà€żà€‚à€—à„à€œ à€Šà„à€°à„à€€à€Șà€Łà„‡ à€…â€à„…à€•à„à€žà„‡à€ž à€•à€°à€Łà„à€Żà€Ÿà€žà€Ÿà€ à„€ à€•à„à€Čà€żà€• à€•à€°à„ à€¶à€•à€€à€Ÿ. à€§à€šà„à€Żà€”à€Ÿà€Š, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ms/messages.json b/_locales/ms/messages.json index 23dd207814..c7878a7232 100644 --- a/_locales/ms/messages.json +++ b/_locales/ms/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Ralat Pangkalan Data", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ralat pangkalan data telah berlaku. Anda boleh menyalin ralat dan menghubungi sokongan Signal untuk membantu menyelesaikan isu tersebut. Jika anda perlu menggunakan Signal dengan segera, anda boleh memadamkan data anda dan mulakan semula.\n\nHubungi sokongan dengan melawati: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Padam semua data dan mula semula", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Padam data dan mula semula", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Padamkan semua data secara kekal?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Semua sejarah mesej dan media anda akan dipadamkan secara kekal daripada peranti ini. Anda akan dapat menggunakan Signal pada peranti ini selepas memautkannya semula. Ini tidak akan memadamkan sebarang data daripada telefon anda.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Versi pangkalan data anda tidak sepadan dengan versi Signal ini. Pastikan anda membuka versi terbaru Signal pada komputer anda.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fail", @@ -300,6 +316,70 @@ "messageformat": "Sembang", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Kesilapan telah berlaku dengan nama pengguna anda, ia tidak lagi diberikan kepada akaun anda. Anda boleh mencuba dan menetapkannya semula atau memilih yang baharu.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Baiki sekarang", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Kesilapan telah berlaku dengan kod QR dan pautan nama pengguna anda, ia tidak lagi sah. Cipta pautan baharu untuk dikongsi dengan orang lain.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Baiki sekarang", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Tunjuk Tab", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Sembunyikan Tab", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ralat telah berlaku", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} belum dibaca", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Ditanda belum dibaca", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Sembang", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Panggilan", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Cerita", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Tetapan", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Kemas Kini Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Kembali", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Sembang ini telah diarkibkan dan hanya akan muncul dalam Peti Masuk jika mesej baharu diterima.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Panggil sahaja", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Sertai juga", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Teruskan Panggilan", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Nombor keselamatan sedang dikemas kini.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Ketahui lebih lanjut", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Nombor Keselamatan sebelumnya", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Nombor Keselamatan seterusnya", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Versi nombor keselamatan, {index,number} daripada {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Tanda sebagai disahkan", @@ -663,33 +747,41 @@ "messageformat": "Kosongkan pengesahan", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Untuk mengesahkan keselamatan penyulitan hujung ke hujung dengan {name}, bandingkan nombor di atas dengan peranti mereka. Mereka juga boleh mengimbas kod anda dengan peranti mereka.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Ketahui lebih lanjut", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Untuk mengesahkan penyulitan hujung ke hujung dengan {name}, padankan kad warna di atas dengan peranti mereka dan bandingkan nombornya. Jika ini tidak sepadan, cuba pasangan nombor keselamatan yang lain. Hanya satu pasangan yang perlu dipadankan.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Untuk mengesahkan keselamatan penyulitan hujung ke hujung dengan {name}, bandingkan nombor di atas dengan peranti mereka. Mereka juga boleh mengimbas kod anda dengan peranti mereka.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Perubahan kepada Nombor Keselamatan", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Nombor keselamatan sedang dikemas kini dalam tempoh peralihan untuk mendayakan ciri privasi yang akan datang dalam Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Untuk mengesahkan nombor keselamatan, padankan kad warna dengan peranti kenalan anda. Jika ini tidak sepadan, cuba pasangan nombor keselamatan yang lain. Hanya satu pasangan yang perlu dipadankan.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Perlukan bantuan?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Faham", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Nombor keselamatan akan dicipta dengan orang ini selepas anda mesej dengan mereka.", @@ -1267,10 +1359,6 @@ "messageformat": "Lihat media terkini", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Untuk mengesahkan keselamatan penyulitan hujung ke hujung anda dengan {name}, bandingkan nombor di atas dengan peranti mereka. Mereka juga boleh mengimbas kod QR di atas.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Anda belum bertukar sebarang mesej dengan kenalan ini lagi. Nombor keselamatan anda dengan mereka akan tersedia selepas mesej pertama." }, @@ -1334,17 +1422,17 @@ "messageformat": "Maklumat", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Padam", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Padam mesej", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Padam sembang?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Padam mesej?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Sembang ini akan dipadam daripada peranti ini.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Mesej dalam sembang ini akan dipadamkan daripada peranti ini. Anda masih boleh mencari sembang ini selepas anda memadamkan mesej.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Keluar kumpulan", @@ -1438,6 +1526,14 @@ "messageformat": "Sejarah mesej anda untuk kedua-dua sembang telah digabungkan di sini.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} milik {conversationTitle}. Anda berdua ahli {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} milik {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Imej kecil daripada mesej yang dipetik", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Panggil Semula", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Mulakan Panggilan", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Sertai Panggilan", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon diredam kerana saiz panggilan", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Pemberitahuan panggilan", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Panggilan penuh", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Sertai", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Mulakan", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Panggilan penuh", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera dinyahdayakan", @@ -1621,10 +1725,6 @@ "messageformat": "Hidupkan kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Redamkan", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon dinyahdayakan", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Nyahredamkan mikrofon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Kongsi", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Pembentangan dinyahdayakan", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Hentikan pembentangan", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Panggil", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Terlalu ramai dalam kumpulan untuk memanggil peserta.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Aktifkan deringan", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Matikan deringan", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Hidupkan deringan", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Lebih pilihan", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Anda", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kamera anda dimatikan", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Lihat Nombor Keselamatan", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mesej", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Lihat Nombor Keselamatan", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Gagal mengambil nombor telefon. Periksa sambungan anda dan cuba lagi.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Edit hanya boleh dibuat dalam masa 3 jam dari masa anda menghantar mesej ini.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Edit hanya boleh digunakan dalam masa 24 jam dari masa anda menghantar mesej ini.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Mesej ini telah dipadam.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Lampiran terlalu besar untuk dipaparkan.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Sesetengah lampiran terlalu besar untuk dipaparkan.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Tidak dapat mengambil butiran derma", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Beta Signal sahaja", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Mengedit mesej tersedia untuk pengguna beta Signal sahaja. Jika anda mengedit mesej, ia hanya akan kelihatan kepada orang yang menggunakan versi terkini beta Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Edit mesej", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Jika anda mengedit mesej, ia hanya akan kelihatan kepada orang yang menggunakan versi terkini Signal. Mereka akan dapat melihat anda mengedit mesej.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Panggilan video masuk...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Panggilan suara keluar", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Panggilan video keluar", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} memanggil anda", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Menyambung semula...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} orang}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Panggilan audio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Tamat", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Tinggalkan", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon dimatikan", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon dihidupkan", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Deringan dihidupkan", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Deringan dimatikan", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Tetapan", @@ -3468,13 +3668,25 @@ "messageformat": "Panggilan skrin penuh", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Tukar ke paparan grid", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Tukar pandangan", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Tukar ke paparan pembentang", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Pandangan grid", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Pandangan bar sisi", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Pandangan pembentang", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Lihat kemas kini", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Tinggalkan panggilan", @@ -3576,6 +3788,14 @@ "messageformat": "Okay", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Tidak boleh mengedit mesej", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Hanya {max,number} edit boleh dibuat pada mesej ini.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Maaf, pautan sgnl:// tidak masuk akal!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nama Pengguna", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Kesilapan telah berlaku dengan nama pengguna anda, ia tidak lagi diberikan kepada akaun anda.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Padam nama pengguna", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Cipta Nama Pengguna", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Kod QR atau Pautan", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Nama pengguna perlu ditetapkan semula", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Pautan nama pengguna perlu ditetapkan semula", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Kongsi Nama Pengguna Anda", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Padam nama pengguna", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Ini akan menyingkirkan nama pengguna anda, membolehkan pengguna lain untuk menuntutnya. Adakah anda pasti?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ini akan mengalih keluar nama pengguna anda dan melumpuhkan kod QR dan pautan anda. “{username}” akan tersedia untuk dituntut oleh orang lain. Adakah anda pasti?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Anda tidak lagi boleh berkongsi atau menonton cerita. Cerita yang anda hantar baru-baru ini juga akan dipadam.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Bahasa", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Bahasa", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Bahasa Sistem", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Cari bahasa", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Tiada hasil untuk “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Tetapkan", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Mulakan semula Signal untuk menggunakannya", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Untuk menukar bahasa, aplikasi perlu dimulakan semula.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Mulakan semula", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Kemas kini kepada versi {version} tersedia", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Terdapat ralat berlaku semasa menyimpan tetapan anda. Sila cuba lagi.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mesej", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Lebih banyak gaya", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Tetap semula", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Selesai", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Warna pautan nama pengguna, {index,number} daripada {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Jika anda menetapkan semula kod QR anda, kod dan pautan QR sedia ada anda tidak akan berfungsi lagi.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Menetapkan semula pautan...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Kod QR dan pautan tidak ditetapkan. Periksa sambungan rangkaian anda dan cuba semula.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Buat nama pengguna Signal anda", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "diedit", + "messageformat": "Diedit", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Hantar Semula", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Lebih tindakan", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Panggilan", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Panggilan baharu", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Panggilan baharu", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Lebih tindakan", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Kosongkan sejarah panggilan", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Kosongkan sejarah panggilan?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Ini akan memadamkan semua sejarah panggilan secara kekal", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Kosongkan", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Sejarah panggilan dikosongkan", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klik untuk melihat atau memulakan panggilan", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Cari", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Tapis mengikut panggilan terlepas", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Togol", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Tiada panggilan terbaru. Mulakan dengan menghubungi rakan.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Tiada hasil untuk “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Panggilan masuk", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Panggilan keluar", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Panggilan terlepas", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Panggilan kumpulan", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Tiada perbualan terbaru.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Tiada hasil untuk “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Panggilan suara keluar} other {Panggilan suara masuk}}} Video {{direction, select, Outgoing {Panggilan video keluar} other {Panggilan video masuk}}} Group {{direction, select, Outgoing {Panggilan kumpulan keluar} other {Panggilan kumpulan masuk}}} other {{direction, select, Outgoing {Panggilan keluar} other {Panggilan masuk}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Panggilan suara terlepas} Video {Panggilan video tidak dijawab} Group {Panggilan kumpulan terlepas} other {Panggilan tidak dijawab}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Panggilan suara tidak dijawab} Video {Panggilan video tidak dijawab} Group {Panggilan kumpulan tidak dijawab} other {Panggilan tidak dijawab}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Panggilan suara ditolak} Video {Panggilan video ditolak} Group {Panggilan kumpulan ditolak} other {Panggilan ditolak}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number} yang lain sedang menaip.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Perkara Baharu", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Sedikit pengubahsuaian, pembaikan pepijat dan peningkatan prestasi. Terima kasih kerana menggunakan Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Kemas kini ini termasuk beberapa peningkatan untuk panggilan suara dan video, serta dokumentasi kecil (terima kasih, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Kini anda boleh menukar bahasa pilihan anda dalam Signal tanpa mengubah tetapan sistem anda (Tetapan Signal > Gaya > Bahasa)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Kami telah mengemas kini beberapa ikon pemberitahuan kumpulan. Ikon baharu ini juga sangat sesuai untuk mereka yang sukakan mod gelap." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Kami telah membaiki kelewatan yang kadangkala terjadi pada macOS selepas menyertai lobi panggilan." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Kami membetulkan animasi peralihan untuk jubin video apabila seseorang menyertai atau meninggalkan panggilan kumpulan." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Kini anda boleh klik pada foto profil atau avatar kumpulan dalam pengepala sembang untuk mengakses tetapan sembang dengan pantas atau melihat sebarang cerita yang tidak kelihatan daripada sembang itu. Terima kasih, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/my/messages.json b/_locales/my/messages.json index 6fc9a449ad..fd88829eeb 100644 --- a/_locales/my/messages.json +++ b/_locales/my/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "á€’á€±á€á€Źá€˜á€±á€·á€…á€ș á€á€»á€­á€Żá€·á€šá€œá€„á€șသချကá€ș", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "á€’á€±á€á€Źá€˜á€±á€·á€…á€ș á€á€»á€­á€Żá€·á€šá€œá€„á€șသချကá€șတစá€șခု ဖဌစá€șနေပါသညá€ș။ á€á€»á€­á€Żá€·á€šá€œá€„á€șသချကá€șကို á€€á€°á€žá€šá€°á€•á€Œá€źá€žá€”á€±á€Źá€€á€ș á€€á€•á€Œá€żá€”á€Źá€€á€­á€Ż ဖဌေရဟငá€șှရနá€șá€Ąá€á€œá€€á€ș ဥကူဥညဟပေသရနá€ș Signal ပံ့ပိုသရေသသို့ ဆကá€șသလယá€șနိုငá€șပါသညá€ș။ Signal ကို သငá€ș ချကá€șချငá€șá€žá€Ąá€žá€Żá€¶á€žá€•á€Œá€Żá€›á€”á€ș လိုအပá€șပါက သင့á€șဒေတဏကို ဖျကá€șá€•á€Œá€źá€ž ပဌနá€șလညá€șစတငá€șနိုငá€șပါသညá€ș။\n\nကလင့á€șခá€șကို ဝငá€șရေဏကá€șခဌငá€șသဖဌင့á€ș ပံ့ပိုသရေသသို့ ဆကá€șသလယá€șပါ- {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ဒေတဏ á€Ąá€Źá€žá€œá€Żá€¶á€žá€€á€­á€Ż ဖျကá€șá€•á€Œá€źá€ž ပဌနá€șလညá€șစတငá€șရနá€ș", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ဒေတဏကို ဖျကá€șá€•á€Œá€źá€ž ပဌနá€șလညá€șစတငá€șရနá€ș", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "á€’á€±á€á€Źá€Ąá€Źá€žá€œá€Żá€¶á€žá€€á€­á€Ż á€Ąá€•á€Œá€źá€žá€Ąá€•á€­á€Żá€„á€șဖျကá€șမညá€șလာှ။", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "သငá€ș၏ မကá€șဆေ့ချá€șမဟတá€șတမá€șသနဟင့á€ș á€™á€źá€’á€źá€šá€Źá€Ąá€Źá€žá€œá€Żá€¶á€žá€€á€­á€Ż ကစကá€șမဟ á€Ąá€•á€Œá€źá€žá€Ąá€•á€­á€Żá€„á€șဖျကá€șလိုကá€șပါမညá€ș။ Signal ကို ပဌနá€șလညá€șချိတá€șဆကá€șá€•á€Œá€źá€žá€”á€±á€Źá€€á€ș ကစကá€șတလငá€ș Signal ကို á€Ąá€žá€Żá€¶á€žá€•á€Œá€Żá€”á€­á€Żá€„á€șပါမညá€ș။ ၎ငá€șှသညá€ș သင့á€șဖုနá€șသမဟ မညá€șသည့á€șá€’á€±á€á€Źá€€á€­á€Żá€™á€»á€Ÿ ဖျကá€șမညá€șမဟုတá€șပါ။", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "သငá€ș၏ á€’á€±á€á€Źá€˜á€±á€·á€…á€șá€—á€Źá€žá€›á€Ÿá€„á€șှသညá€ș က Signal á€—á€Źá€žá€›á€Ÿá€„á€șသနဟင့á€ș မကိုကá€șညဟပါ။ သင့á€șကလနá€șá€•á€»á€°á€á€Źá€á€œá€„á€ș Signal နေဏကá€șá€†á€Żá€¶á€žá€‘á€œá€€á€șá€—á€Źá€žá€›á€Ÿá€„á€șှကို ဖလင့á€șá€‘á€Źá€žá€á€Œá€„á€șသဖဌစá€șá€€á€Œá€±á€Źá€„á€șှ သေချဏဥေဏငá€șလုပá€șပါ။", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ဖိုငá€ș", @@ -300,6 +316,70 @@ "messageformat": "ချကá€ș(တá€ș)မျဏသ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "သငá€ș၏ á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șနဟင့á€șပတá€șသကá€ș၍ တစá€șစုံတစá€șခု á€™á€Ÿá€Źá€žá€šá€œá€„á€șသနေပါသညá€ș၊ ၎ငá€șှကို သင့á€șဥကေဏင့á€șá€Ąá€á€œá€€á€ș သတá€șမဟတá€șá€‘á€Źá€žá€á€Œá€„á€șှ á€™á€›á€Ÿá€­á€á€±á€Źá€·á€•á€«á‹ ထပá€șá€™á€¶á€€á€Œá€­á€Żá€žá€…á€Źá€žá သတá€șမဟတá€șနိုငá€șပါသညá€ș á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș အမညá€șအသစá€șတစá€șခု ရလေသချယá€șနိုငá€șပါသညá€ș။", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ယခု ဖဌေရဟငá€șှရနá€ș", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "သငá€ș၏ QR ကုဒá€șနဟင့á€ș á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€ș လင့á€șခá€șတလငá€ș တစá€șစုံတစá€șခု á€™á€Ÿá€Źá€žá€šá€œá€„á€șသနေပါသညá€ș၊ ၎ငá€șှသညá€ș မဟနá€șကနá€șခဌငá€șá€žá€™á€›á€Ÿá€­á€á€±á€Źá€·á€•á€«á‹ á€Ąá€á€Œá€Źá€žá€žá€°á€™á€»á€Źá€žá€”á€Ÿá€„á€·á€ș မျဟဝေပေသရနá€ș လင့á€șခá€șအသစá€șတစá€șခု ဖနá€șတဟသပါ။", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ယခု ဖဌေရဟငá€șှရနá€ș", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "တကá€șဘá€șမျဏသကို ပဌသရနá€ș", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "တကá€șဘá€șမျဏသကို ဖျေဏကá€șထာှရနá€ș", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "á€á€»á€­á€Żá€·á€šá€œá€„á€șသချကá€ș ဖဌစá€șပေါá€șခá€Č့ပါသညá€ș", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ခု မဖတá€șရသေသ", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "မဖတá€șá€›á€žá€±á€žá€Ÿá€Ż မဟတá€șá€•á€Œá€źá€ž", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ချကá€ș(တá€ș)မျဏသ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ဖုနá€șသခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€™á€»á€Źá€ž", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "စတိုရဟမျဏသ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "á€Ąá€•á€Œá€„á€șအဆငá€șမျဏသ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal အာှအဆငá€ș့မဌဟငá€ș့မယá€ș", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ပရိုဖိုငá€ș", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "နေဏကá€șသို့", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ထိုချကá€ș(တá€ș)မျဏသကို မဟတá€șတမá€șှတငá€șá€‘á€Źá€žá€•á€Œá€źá€ž မကá€șဆေ့ချá€șအသစá€șမျဏသ လကá€șခံရရဟိခá€Č့လျဟငá€șသာ ဝငá€șစဏပုံသထá€Čတလငá€ș ပေါá€șနေပါလိမá€ș့မညá€ș။", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ဘာပá€Čဖဌစá€șဖဌစá€șဖုနá€șသခေါá€șပါ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "မညá€șသို့ပငá€șဖဌစá€șစေ ပါဝငá€șမညá€ș", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€žá€­á€Żá€· ဆကá€șမယá€ș", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€șမျဏသကို အပá€șဒိတá€șá€•á€Œá€Żá€œá€Żá€•á€șနေပါသညá€ș။", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ထပá€șá€™á€¶á€œá€±á€·á€œá€Źá€›á€”á€ș", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ယခငá€ș á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "နေဏကá€șá€œá€Źá€™á€Šá€·á€ș á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș á€—á€Źá€žá€›á€Ÿá€„á€șှ၊ {total,number} ခုထá€Čမဟ {index,number} á€á€Żá€™á€Œá€±á€Źá€€á€ș", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "အတညá€șá€•á€Œá€Żá€•á€Œá€źá€ž á€Ąá€™á€Ÿá€á€șအသာှ", @@ -663,33 +747,41 @@ "messageformat": "အတညá€șá€•á€Œá€Żá€™á€Ÿá€Ż ရဟငá€șှလငá€șှရနá€ș", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} နဟင့á€ș ဟိုဘကá€șသညá€șဘကá€ș ကုဒá€șá€•á€Œá€±á€Źá€„á€șသဝဟကá€șá€‘á€Źá€žá€á€Œá€„á€șှကို စိစစá€șအတညá€șá€•á€Œá€Żá€›á€”á€ș အထကá€șပါနံပါတá€șမျဏသကို ၎ငá€șှ၏စကá€șနဟင့á€ș á€”á€Ÿá€­á€Żá€„á€șသယဟဉá€șပါ။ ၎ငá€șá€žá€Ąá€”á€±á€–á€Œá€„á€·á€ș သင့á€șကုဒá€șကိုလညá€șှ ၎ငá€șှ၏စကá€șဖဌင့á€ș စကနá€șဖတá€șနိုငá€șပါသညá€ș။", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "á€•á€­á€Żá€™á€­á€Żá€žá€­á€›á€Ÿá€­á€›á€”á€ș", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} နဟင့á€ș ဟိုဘကá€șသညá€șဘကá€ș ကုဒá€șá€•á€Œá€±á€Źá€„á€șသဝဟကá€șá€‘á€Źá€žá€á€Œá€„á€șှကို စိစစá€șအတညá€șá€•á€Œá€Żá€›á€”á€ș အထကá€șပါ ဥရေဏငá€șကတá€șá€•á€Œá€Źá€žá€€á€­á€Ż ၎ငá€șှ၏စကá€șနဟင့á€ș ယဟဉá€șကဌည့á€șá€•á€Œá€źá€ž နံပါတá€șမျဏသကို á€”á€Ÿá€­á€Żá€„á€șသယဟဉá€șပါ။ ထိုနံပါတá€șမျဏသ မကိုကá€șညဟပါက á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș နေဏကá€șတစá€șတလá€Čဖဌင့á€ș စမá€șသကဌည့á€șပါ။ နံပါတá€șá€Ąá€á€œá€Čတစá€șတလá€Čá€žá€Źá€œá€»á€Ÿá€„á€ș ကိုကá€șညြရနá€ș လိုအပá€șပါသညá€ș။", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} နဟင့á€ș ဟိုဘကá€șသညá€șဘကá€ș ကုဒá€șá€•á€Œá€±á€Źá€„á€șသဝဟကá€șá€‘á€Źá€žá€á€Œá€„á€șှကို စိစစá€șအတညá€șá€•á€Œá€Żá€›á€”á€ș အထကá€șပါနံပါတá€șမျဏသကို ၎ငá€șှ၏စကá€șနဟင့á€ș á€”á€Ÿá€­á€Żá€„á€șသယဟဉá€șပါ။ ၎ငá€șá€žá€Ąá€”á€±á€–á€Œá€„á€·á€ș သင့á€șကုဒá€șကိုလညá€șှ ၎ငá€șှ၏စကá€șဖဌင့á€ș စကနá€șဖတá€șနိုငá€șပါသညá€ș။", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€șမျဏသဆိုငá€șရာ á€Ąá€•á€Œá€±á€Źá€„á€șှအလá€Čမျဏသ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal တလငá€ș ပါဝငá€șá€œá€Źá€™á€Šá€·á€ș ကိုယá€șပိုငá€șဥချကá€șအလကá€șဆိုငá€șရာ အငá€șá€čဂါရပá€șမျဏသကို ဖလင့á€șနိုငá€șရနá€șá€Ąá€á€œá€€á€ș á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€șမျဏသကို á€Ąá€€á€°á€žá€Ąá€•á€Œá€±á€Źá€„á€șှကာလတစá€șá€á€Żá€Ąá€á€œá€„á€șှ အပá€șဒိတá€șá€•á€Œá€Żá€œá€Żá€•á€șနေပါသညá€ș။", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€șမျဏသကို စိစစá€șအတညá€șá€•á€Œá€Żá€›á€”á€ș ဥရေဏငá€șကတá€șá€•á€Œá€Źá€žá€€á€­á€Ż သင့á€șအဆကá€șá€Ąá€žá€œá€šá€ș၏စကá€șနဟင့á€ș ယဟဉá€șကဌည့á€șပါ။ ထိုနံပါတá€șမျဏသ မကိုကá€șညဟပါက á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș နေဏကá€șတစá€șတလá€Čဖဌင့á€ș စမá€șသကဌည့á€șပါ။ နံပါတá€șá€Ąá€á€œá€Čတစá€șတလá€Čá€žá€Źá€œá€»á€Ÿá€„á€ș ကိုကá€șညြရနá€ș လိုအပá€șပါသညá€ș။", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "အကူအညြ လိုအပá€șá€•á€«á€žá€œá€Źá€ž?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "á€›á€•á€Œá€ź", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ကပုဂá€čဂိုလá€șနဟင့á€ș သငá€ș မကá€șဆေ့ချá€șမျဏသ á€Ąá€•á€Œá€”á€șá€Ąá€œá€Ÿá€”á€șá€•á€±á€žá€•á€­á€Żá€·á€•á€Œá€źá€žá€žá€±á€Źá€Ąá€á€« ၎ငá€șသနဟင့á€șသကá€șဆိုငá€șသေဏ á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€șတစá€șခုကို ဖနá€șတြှလိုကá€șပါမညá€ș။", @@ -1267,10 +1359,6 @@ "messageformat": "á€™á€€á€Œá€Źá€™á€źá€€ မြဒြယာကို ကဌည့á€șရနá€ș", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} နဟင့á€ș သငá€ș၏ ဟိုဘကá€șသညá€șဘကá€ș ကုဒá€șá€•á€Œá€±á€Źá€„á€șသဝဟကá€șá€™á€Ÿá€Ż á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€€á€­á€Ż စိစစá€șအတညá€șá€•á€Œá€Żá€›á€”á€ș အထကá€șပါနံပါတá€șမျဏသကို ၎ငá€șှ၏စကá€șနဟင့á€ș á€”á€Ÿá€­á€Żá€„á€șသယဟဉá€șပါ။ ၎ငá€șá€žá€Ąá€”á€±á€–á€Œá€„á€·á€ș အထကá€șပါ qr ကုဒá€șကိုလညá€șှ စကနá€șဖတá€șနိုငá€șပါသညá€ș။", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "You haven't exchanged any messages with this contact yet. Your safety number with them will be available after the first message." }, @@ -1334,17 +1422,17 @@ "messageformat": "ဥချကá€șအလကá€ș", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ဖျကá€șရနá€ș", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "မကá€șဆေ့ချá€șမျဏသကို ဖျကá€șရနá€ș", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ချကá€ș(တá€ș)ကို ဖျကá€șမညá€șလာှ။", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "မကá€șဆေ့ချá€șမျဏသကို ဖျကá€șမညá€șလာှ။", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ကချကá€ș(တá€ș)ကို ယခုစကá€șမဟ ဖျကá€șလိုကá€șပါမညá€ș။", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ကချကá€ș(တá€ș)မဟ မကá€șဆေ့ချá€șမျဏသကို ယခုစကá€șမဟ ဖျကá€șလိုကá€șပါမညá€ș။ မကá€șဆေ့ချá€șမျဏသကို ဖျကá€șá€•á€Œá€źá€žá€”á€±á€Źá€€á€ș ကချကá€ș(တá€ș)ကို သငá€ș á€›á€Ÿá€Źáá€›á€•á€«á€žá€±á€žá€žá€Šá€ș။", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "á€Ąá€–á€œá€Č့မဟ ထလကá€șမညá€ș", @@ -1438,6 +1526,14 @@ "messageformat": "ချကá€ș(တá€ș)နဟစá€șá€á€Żá€œá€Żá€¶á€žá€Ąá€á€œá€€á€ș သင့á€șမကá€șဆေ့ချá€șမဟတá€șတမá€șှကို á€€á€”á€±á€›á€Źá€á€œá€„á€ș ပေါငá€șှစညá€șသထဏသပါသညá€ș။", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} ကို {conversationTitle} က ပိုငá€șဆိုငá€șပါသညá€ș။ သငá€șတို့သညá€ș {sharedGroup} á€Ąá€–á€œá€Č့ဝငá€șမျဏသ ဖဌစá€șပါသညá€ș။", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} ကို {conversationTitle} က ပိုငá€șဆိုငá€șပါသညá€ș", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Quote လုပá€șထဏသသေဏ မကá€șဆေ့ချá€șမဟ á€•á€Żá€¶á€€á€Œá€™á€șှ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ပဌနá€șခေါá€șဆိုပါ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ခေါá€șá€†á€­á€Żá€™á€Ÿá€Ż စတငá€șမယá€ș", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€‘á€Čဝငá€șမယá€ș", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "á€€á€±á€Źá€œá€ș á€Ąá€›á€œá€šá€șá€Ąá€…á€Źá€žá€€á€Œá€±á€Źá€„á€·á€ș မိုကá€șခရိုဖုနá€șှ ဥသံပိတá€șထာှသညá€ș", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "á€€á€±á€Źá€œá€ș ဥသိပေသချကá€șမျဏသ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€•á€Œá€Šá€·á€șá€žá€œá€Źá€žá€á€šá€ș", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ကငá€șမရာ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ပါဝငá€șမညá€ș", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ဖုနá€șသစခေါá€șမညá€ș", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "á€€á€±á€Źá€œá€șတလငá€ș လူပဌည့á€șá€”á€±á€•á€Œá€ź", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ကငá€șမရာ ပိတá€șထာှသညá€ș", @@ -1621,10 +1725,6 @@ "messageformat": "ကငá€șမရာ ဖလင့á€șရနá€ș", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ဥသံပိတá€șရနá€ș", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "မိုကá€șခရိုဖုနá€șှ ပိတá€șထာှသညá€ș", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "မိုကá€ș á€Ąá€žá€¶á€•á€Œá€”á€șဖလင့á€șရနá€ș", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ဝေမျဟမယá€ș", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "á€•á€Œá€žá€™á€Ÿá€Ż ပိတá€șထာှသညá€ș", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "á€•á€Œá€žá€™á€Ÿá€Ż ရပá€șရနá€ș", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ဖုနá€șသခေါá€șရနá€ș", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ပါဝငá€șသူမျဏသကို ဖုနá€șသခေါá€șရနá€ș á€Ąá€–á€œá€Č့သညá€ș á€€á€Œá€źá€žá€œá€œá€”á€șသနေပါသညá€ș။", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ဥချကá€șပေသမဌညá€șသံကို ဖလင့á€șရနá€ș", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ဖုနá€șသမဌညá€șသံ ပိတá€șရနá€ș", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ဖုနá€șသမဌညá€șသံ ဖလင့á€șရနá€ș", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "နေဏကá€șထပá€ș á€›á€œá€±á€žá€…á€›á€Źá€™á€»á€Źá€ž", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "သငá€ș", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "သငá€ș့ ကငá€șမရာ ပိတá€șထဏသပါသညá€ș", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș ကဌည့á€șရနá€ș", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "မကá€șဆေ့ချá€ș", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "á€œá€Żá€¶á€á€Œá€Żá€¶á€›á€±á€žá€”á€¶á€•á€«á€á€ș ကဌည့á€șရနá€ș", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ဖုနá€șသနံပါတá€ș ထည့á€șခဌငá€șှ မဥေဏငá€șမဌငá€șပါ။ သင့á€șချိတá€șဆကá€șá€™á€Ÿá€Żá€€á€­á€Ż စစá€șá€†á€±á€žá€•á€Œá€źá€ž ထပá€șá€€á€Œá€­á€Żá€žá€…á€Źá€žá€•á€«á‹", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ထိုမကá€șဆေ့ချá€șကို ပေသပို့ခá€Č့ချိနá€șမဟ 3 á€”á€Źá€›á€źá€Ąá€á€œá€„á€șှ၌သာ တညá€șသဖဌတá€șá€™á€Ÿá€Ż လုပá€șနိုငá€șပါသညá€ș။", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ထိုမကá€șဆေ့ချá€șကို ပေသပို့ခá€Č့ချိနá€șမဟ 24 á€”á€Źá€›á€źá€Ąá€á€œá€„á€șှ၌သာ တညá€șသဖဌတá€șá€™á€Ÿá€Ż လုပá€șနိုငá€șပါသညá€ș။", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ကမကá€șဆေ့ဥဏသ ဖျကá€șá€•á€Œá€źá€žá€•á€«á€•á€Œá€źá‹", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ပူသတလá€Čဖိုငá€șá€™á€Ÿá€Ź ပဌသရနá€ș á€€á€Œá€źá€žá€œá€œá€”á€șသနေသညá€ș။", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ပူသတလá€Čဖိုငá€șá€Ąá€á€»á€­á€Żá€·á€™á€Ÿá€Ź ပဌသရနá€ș á€€á€Œá€źá€žá€œá€œá€”á€șသနေသညá€ș။", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "လဟူဒါနá€șá€žá€™á€Ÿá€Ż ဥသေသစိတá€șကို ရယူ၍ မရနိုငá€șပါ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal Beta သြှသနá€ș့", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "မကá€șဆေ့ချá€șမျဏသ တညá€șသဖဌတá€șခဌငá€șှကို Signal Beta á€žá€Żá€¶á€žá€…á€œá€Čá€žá€°á€™á€»á€Źá€žá€Ąá€á€œá€€á€șသာ á€›á€›á€Ÿá€­á€”á€­á€Żá€„á€șပါသညá€ș။ မကá€șဆေ့ချá€șတစá€șစေဏငá€șကို တညá€șသဖဌတá€șပါက ၎ငá€șှကို Signal Beta နေဏကá€șá€†á€Żá€¶á€žá€‘á€œá€€á€șá€—á€Źá€žá€›á€Ÿá€„á€șá€žá€›á€Ÿá€­á€žá€°á€™á€»á€Źá€žá€žá€Ź မဌငá€șရပါမညá€ș။", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "မကá€șဆေ့ချá€ș တညá€șသဖဌတá€șရနá€ș", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "မကá€șဆေ့ချá€șတစá€șစေဏငá€șကို တညá€șသဖဌတá€șပါက ၎ငá€șှကို Signal နေဏကá€șá€†á€Żá€¶á€žá€‘á€œá€€á€șá€—á€Źá€žá€›á€Ÿá€„á€șသမျဏသကို သုံသနေသူမျဏသသဏ မဌငá€șရပါမညá€ș။ ၎ငá€șသတို့သညá€ș မကá€șဆေ့ချá€șတစá€șစေဏငá€șကို သငá€ș တညá€șသဖဌတá€șလိုကá€șá€€á€Œá€±á€Źá€„á€șှ တလေ့မဌငá€șရပါမညá€ș။", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "á€—á€źá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș ဝငá€șနေသညá€ș...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "á€Ąá€‘á€œá€€á€ș ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "á€—á€źá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș á€Ąá€‘á€œá€€á€ș", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} က သင့á€șကို ခေါá€șနေသညá€ș", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ပဌနá€șချိတá€șဆကá€șနေဆá€Č...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} ဩှ}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ဥဆုံသသတá€șမညá€ș", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ထလကá€șမညá€ș", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "မိုကá€ș ပိတá€șထာှသညá€ș", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "မိုကá€ș ဖလင့á€șထာှသညá€ș", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ဖုနá€șသမဌညá€șသံ ဖလင့á€șထာှသညá€ș", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ဖုနá€șသမဌညá€șသံ ပိတá€șထာှသညá€ș", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "á€Ąá€•á€Œá€„á€șအဆငá€șမျဏသ", @@ -3468,13 +3668,25 @@ "messageformat": "á€€á€±á€Źá€œá€șကို စခရငá€șá€Ąá€•á€Œá€Šá€·á€ș လုပá€șရနá€ș", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "á€Ąá€€á€œá€€á€șပုံစံသို့ á€•á€Œá€±á€Źá€„á€șှရနá€ș", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "မဌငá€șကလငá€șှ á€•á€Œá€±á€Źá€„á€șှရနá€ș", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "á€•á€Œá€±á€Źá€žá€°á€Ąá€Źá€ž ကဌည့á€șá€›á€Ÿá€Żá€žá€Šá€·á€șပုံစံသို့ á€•á€Œá€±á€Źá€„á€șှရနá€ș", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "á€Ąá€€á€œá€€á€șလိုကá€ș မဌငá€șကလငá€șှ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "á€˜á€±á€žá€˜á€Źá€žá€á€”á€șှ မဌငá€șကလငá€șှ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "á€…á€€á€Źá€žá€•á€Œá€±á€Źá€žá€° မဌငá€șကလငá€șှ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "မဌငá€șကလငá€șှအသစá€șဖဌင့á€ș ကဌည့á€șရနá€ș", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ဖုနá€șသခေါá€șပါ", @@ -3576,6 +3788,14 @@ "messageformat": "ဥိုကေ", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "မကá€șဆေ့ချá€ș တညá€șသဖဌတá€ș၍မရပါ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ကမကá€șဆေ့ချá€șကို {max,number} ကဌိမá€șအထိသာ တညá€șသဖဌတá€ș၍ရပါသညá€ș။", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ဝမá€șှနညá€șသပါသညá€ș၊ ထို sgnl:// လင့á€șခá€șသညá€ș မမဟနá€șကနá€șပါ။", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€ș", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "သငá€ș၏ á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șနဟင့á€șပတá€șသကá€ș၍ တစá€șစုံတစá€șခု á€™á€Ÿá€Źá€žá€šá€œá€„á€șသနေပါသညá€ș၊ ၎ငá€șှကို သင့á€șဥကေဏင့á€șá€Ąá€á€œá€€á€ș သတá€șမဟတá€șá€‘á€Źá€žá€á€Œá€„á€șှ á€™á€›á€Ÿá€­á€á€±á€Źá€·á€•á€«á‹", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို ဖျကá€șရနá€ș", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€ș ဖနá€șတြှရနá€ș", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ကုဒá€ș á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș လင့á€șခá€ș", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို ပဌနá€șလညá€șသတá€șမဟတá€șရနá€ș လိုအပá€șသညá€ș", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€ș လင့á€șခá€șကို ပဌနá€șလညá€șသတá€șမဟတá€șရနá€ș လိုအပá€șသညá€ș", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "သငá€ș၏ á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို ဝေမျဟရနá€ș", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို ဖျကá€șရနá€ș", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ကသညá€șá€™á€Ÿá€Ź သငá€ș၏ á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို ဖယá€șá€›á€Ÿá€Źá€žá€•á€Œá€źá€ž á€Ąá€á€Œá€Źá€žá€žá€Żá€¶á€žá€…á€œá€Čသူမျဏသဥဏသ ၎ငá€șှကို á€›á€šá€°á€žá€Żá€¶á€žá€…á€œá€Čခလငá€șá€·á€•á€Œá€Żá€”á€­á€Żá€„á€șပါသညá€ș။ လုပá€șလိုသညá€șá€™á€Ÿá€Ź á€žá€±á€á€»á€Źá€•á€«á€žá€œá€Źá€žá‹", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "၎ငá€șှသညá€ș သငá€ș၏ á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို ဖယá€șá€›á€Ÿá€Źá€žá€œá€­á€Żá€€á€șမညá€șဖဌစá€șá€•á€Œá€źá€ž သင့á€ș QR ကုဒá€șနဟင့á€ș လင့á€șခá€șကို ဖျကá€șလိုကá€șပါမညá€ș။ \"{username}\" ကို á€Ąá€á€Œá€Źá€žá€žá€°á€™á€»á€Źá€ž á€Ąá€žá€Żá€¶á€žá€•á€Œá€Żáá€›á€žá€œá€Źá€žá€•á€«á€œá€­á€™á€·á€șမညá€ș။ á€žá€±á€á€»á€Źá€•á€«á€žá€œá€Źá€žá‹", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "သငá€șသညá€ș စတိုရဟမျဏသ ဝေမျဟရနá€ș á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș ကဌညá€ș့ရနá€ș လုပá€șဆေဏငá€șနိုငá€șတေဏ့မညá€ș မဟုတá€șပါ။ á€™á€€á€Œá€Źá€žá€±á€žá€™á€źá€€ သငá€ș á€á€±á€™á€»á€Ÿá€‘á€Źá€žá€žá€Šá€ș့ အပá€șဒိတá€șá€™á€»á€Źá€žá€€á€­á€Żá€œá€Šá€șှ ဖျကá€șပစá€șပါမညá€ș။", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ဘာသာစကာှ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ဘာသာစကာှ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "စနစá€șသုံသ ဘာသာစကာှ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "á€˜á€Źá€žá€Źá€…á€€á€Źá€žá€™á€»á€Źá€žá€€á€­á€Ż á€›á€Ÿá€Źá€–á€œá€±á€›á€”á€ș", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” á€Ąá€á€œá€€á€ș ရလဒá€șမရဟိပါ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "သတá€șမဟတá€șမညá€ș", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "á€Ąá€žá€Żá€¶á€žá€•á€Œá€Żá€›á€”á€ș Signal ကို ပဌနá€șလညá€șစတငá€șပါ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "á€˜á€Źá€žá€Źá€…á€€á€Źá€žá€•á€Œá€±á€Źá€„á€șှရနá€șá€Ąá€á€œá€€á€ș အကá€șပá€șကို ပဌနá€șလညá€șစတငá€șရနá€ș လိုအပá€șပါသညá€ș။", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ပဌနá€șစတငá€șမညá€ș", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "á€—á€Źá€žá€›á€Ÿá€„á€șှ {version} á€Ąá€á€œá€€á€ș အပá€șဒိတá€ș á€›á€›á€Ÿá€­á€•á€«á€•á€Œá€ź", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "သငá€ș့ဆကá€șတငá€șကို သိမá€șသချိနá€șတလငá€ș á€•á€Œá€żá€”á€Ź ရဟိခá€Č့ပါသညá€ș။ နေဏကá€șမဟ ထပá€șá€€á€Œá€­á€Żá€žá€…á€Źá€žá€•á€±á€žá€•á€«á‹", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "မကá€șဆေ့ချá€ș", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "နေဏကá€șထပá€șစတိုငá€șမျဏသ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ရြဆကá€șချမညá€ș", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "á€•á€Œá€źá€žá€•á€«á€•á€Œá€ź", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șá€Ąá€á€œá€€á€ș လင့á€șခá€șဥရေဏငá€ș၊ {index,number} / {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "သငá€ș၏ QR ကုဒá€șကို သငá€ș ပဌနá€șလညá€șသတá€șမဟတá€șလိုကá€șပါက မူလ QR ကုဒá€șနဟင့á€ș လင့á€șခá€șá€™á€Ÿá€Ź အလုပá€șလုပá€șတေဏ့မညá€șမဟုတá€șပါ။", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "လင့á€șခá€șကို ပဌနá€șလညá€șသတá€șမဟတá€șနေဆá€Č
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR ကုဒá€șနဟင့á€ș လင့á€șခá€șကို မသတá€șမဟတá€șထဏသပါ။ သင့á€șကလနá€șရကá€ș ချိတá€șဆကá€șá€™á€Ÿá€Żá€€á€­á€Ż စစá€șá€†á€±á€žá€•á€Œá€źá€ž ထပá€șá€€á€Œá€­á€Żá€žá€…á€Źá€žá€•á€«á‹", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "သငá€ș၏ Signal á€žá€Żá€¶á€žá€…á€œá€Čသူအမညá€șကို သတá€șမဟတá€șပါ", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "နေဏကá€șတစá€șကဌိမá€ș ပို့ပါ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "နေဏကá€șထပá€ș လုပá€șဆေဏငá€șá€™á€Ÿá€Żá€™á€»á€Źá€ž", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ဖုနá€șသခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€™á€»á€Źá€ž", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "á€€á€±á€Źá€œá€șအသစá€ș", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "á€€á€±á€Źá€œá€șအသစá€ș", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "နေဏကá€șထပá€ș လုပá€șဆေဏငá€șá€™á€Ÿá€Żá€™á€»á€Źá€ž", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "á€€á€±á€Źá€œá€șမဟတá€șတမá€șှကို ရဟငá€șှရနá€ș", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "á€€á€±á€Źá€œá€șမဟတá€șတမá€șှကို ရဟငá€șှမညá€șလာှ။", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "á€€á€žá€­á€Żá€·á€œá€Żá€•á€șဆေဏငá€șခဌငá€șသဖဌငá€ș့ á€€á€±á€Źá€œá€șမဟတá€șတမá€șှ á€Ąá€Źá€žá€œá€Żá€¶á€žá€€á€­á€Ż á€Ąá€•á€Œá€źá€žá€á€­á€Żá€„á€ș ဖျကá€șပစá€șလိုကá€șပါမညá€ș။", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ဖယá€șá€›á€Ÿá€Źá€žá€™á€Šá€ș", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "á€€á€±á€Źá€œá€șမဟတá€șတမá€șှ ရဟငá€șှလငá€șá€žá€•á€Œá€źá€ž", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "á€€á€±á€Źá€œá€șတစá€șခုကို ကဌည့á€șá€›á€Ÿá€Żá€›á€”á€ș á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș စတငá€șရနá€ș နဟိပá€șပါ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "á€›á€Ÿá€Źá€›á€”á€ș", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "လလတá€șá€žá€œá€Źá€žá€žá€Šá€șမျဏသကို စစá€șထုတá€șရနá€ș", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "á€•á€Żá€¶á€…á€¶á€•á€Œá€±á€Źá€„á€șှရနá€ș", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "လတá€șá€á€œá€±á€Ź ခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€™á€»á€Źá€žá€™á€›á€Ÿá€­á‹ သူငယá€șချငá€șှတစá€șယေဏကá€șကို ခေါá€șá€†á€­á€Żá€á€Œá€„á€șသဖဌင့á€ș စတငá€șလိုကá€șပါ။", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” á€Ąá€á€œá€€á€ș ရလဒá€șမရဟိပါ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "အဝငá€ș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "á€Ąá€‘á€œá€€á€ș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "လလတá€șá€žá€œá€Źá€žá€žá€Šá€ș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "á€Ąá€–á€œá€Čá€·á€œá€­á€Żá€€á€ș ခေါá€șá€†á€­á€Żá€™á€Ÿá€Ż", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "လတá€șá€á€œá€±á€Ź á€…á€€á€Źá€žá€•á€Œá€±á€Źá€†á€­á€Żá€™á€Ÿá€Żá€™á€»á€Źá€ž မရဟိပါ။", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” á€Ąá€á€œá€€á€ș ရလဒá€șမရဟိပါ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {á€Ąá€‘á€œá€€á€ș ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș} other {အဝငá€ș ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș}}} Video {{direction, select, Outgoing {á€—á€źá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș á€Ąá€‘á€œá€€á€ș} other {á€—á€źá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș အဝငá€ș}}} Group {{direction, select, Outgoing {á€Ąá€‘á€œá€€á€ș á€Ąá€–á€œá€Čá€·á€€á€±á€Źá€œá€ș} other {အဝငá€ș á€Ąá€–á€œá€Čá€·á€€á€±á€Źá€œá€ș}}} other {{direction, select, Outgoing {ဖုနá€șသခေါá€șá€†á€­á€Żá€™á€Ÿá€Ż} other {အဝငá€șဖုနá€șှလာသညá€ș}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {လလတá€șá€žá€œá€Źá€žá€žá€±á€Ź ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș} Video {ဗဟဒဟယိုခေါá€șá€†á€­á€Żá€™á€Ÿá€Żá€œá€œá€Čချေဏá€ș} Group {လလတá€șá€žá€œá€Źá€žá€žá€±á€Ź á€Ąá€–á€œá€Čá€·á€€á€±á€Źá€œá€ș} other {လလတá€șá€žá€œá€Źá€žá€žá€±á€Ź ဖုနá€șသခေါá€șá€†á€­á€Żá€™á€Ÿá€Ż}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {á€™á€–á€Œá€±á€†á€­á€Żá€žá€±á€Ź ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș} Video {á€™á€–á€Œá€±á€†á€­á€Żá€žá€±á€Ź á€—á€źá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș} Group {á€™á€–á€Œá€±á€†á€­á€Żá€á€Č့သေဏ á€Ąá€–á€œá€Čá€·á€€á€±á€Źá€œá€ș} other {á€™á€–á€Œá€±á€†á€­á€Żá€á€Č့သေဏ á€€á€±á€Źá€œá€ș}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ငဌငá€șှပယá€șခá€Č့သေဏ ဥေဏá€șá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș} Video {ငဌငá€șှပယá€șခá€Č့သေဏ á€—á€źá€’á€źá€šá€­á€Żá€€á€±á€Źá€œá€ș} Group {ငဌငá€șှပယá€șခá€Č့သေဏ á€Ąá€–á€œá€Čá€·á€€á€±á€Źá€œá€ș} other {ငဌငá€șှပယá€șခá€Č့သေဏ á€€á€±á€Źá€œá€ș}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {á€Ąá€á€Œá€Źá€ž {count,number} ဩှ စာရိုကá€șနေသညá€ș။}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "အသစá€șမျဏသ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ဥနေဥထဏသ á€•á€Œá€Żá€•á€Œá€„á€șá€™á€Ÿá€Żá€œá€±á€žá€™á€»á€Źá€žáŠ á€á€»á€­á€Żá€·á€šá€œá€„á€șသချကá€ș ပဌငá€șဆငá€șá€™á€Ÿá€Żá€™á€»á€Źá€žá€”á€Ÿá€„á€ș့ စလမá€șသဆေဏငá€șရညá€ș မဌဟငá€ș့တငá€șá€™á€Ÿá€Żá€™á€»á€Źá€žá‹ Signal ကို သုံသသညá€șá€·á€Ąá€á€œá€€á€ș ကျေသဇူသတငá€șပါသညá€ș။", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ယခုအပá€șဒိတá€șတလငá€ș ဥေဏá€șá€’á€źá€šá€­á€Żá€”á€Ÿá€„á€·á€ș ဗြဒြယို á€€á€±á€Źá€œá€șá€™á€»á€Źá€žá€Ąá€á€œá€€á€ș တိုှတကá€șá€™á€Ÿá€Żá€Ąá€”á€Šá€șှငယá€șနဟင့á€ș á€…á€Źá€›á€œá€€á€șစာတမá€șှဆိုငá€șရာ ဥသေသစဏသဥပá€șဒိတá€șဥချို့ ပါဝငá€șပါသညá€ș (ကျေသဇူသပါ၊ {linkToGithub})။" + "icu:WhatsNew__v6.39--0": { + "messageformat": "ယခုဥခါ သင့á€șစနစá€șဆကá€șတငá€șကို á€™á€•á€Œá€±á€Źá€„á€șှဘá€Č Signal တလငá€ș သငá€ș á€›á€œá€±á€žá€‘á€Źá€žá€žá€±á€Ź ဘာသာစကာှကို á€•á€Œá€±á€Źá€„á€șှနိုငá€șá€•á€«á€•á€Œá€ź (Signal ဆကá€șတငá€ș > ပုံပနá€șသသလငá€șပဌငá€ș > ဘာသာစကာှ)။" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "á€Ąá€–á€œá€Č့ ဥသိပေသချကá€șအိုငá€șကလနá€șဥချို့ကို ကျလနá€șုပá€șတို့ အပá€șဒိတá€șလုပá€șထဏသပါသညá€ș။ ထိုအိုငá€șကလနá€șမျဏသသညá€ș á€Ąá€‘á€°á€žá€žá€–á€Œá€„á€·á€ș á€Ąá€™á€Ÿá€±á€Źá€„á€ș Theme ကို á€Ąá€žá€Żá€¶á€žá€•á€Œá€Żá€•á€«á€€ á€•á€­á€Żáá€›á€Ÿá€„á€șှလငá€șသပဟသစေရနá€ș ဥကူဥညဟပေသပါသညá€ș။ ယခငá€șအိုငá€șကလနá€șမျဏသသညá€ș အလငá€șသမဟ á€Ąá€™á€Ÿá€±á€Źá€„á€șသို့ á€•á€Œá€±á€Źá€„á€șှလိုကá€șá€›á€Żá€¶á€™á€»á€Ÿ ဖဌစá€șပါသညá€ș။ အိုငá€șကလနá€șအသစá€șá€™á€»á€Źá€žá€™á€Ÿá€Źá€™á€° á€Ąá€™á€Ÿá€±á€Źá€„á€șဖဌင့á€șသုံသရနá€ș ချိနá€șညဟိဖနá€șá€á€źá€žá€‘á€Źá€žá€á€Œá€„á€șှ ဖဌစá€șပါသညá€ș။" + "icu:WhatsNew__v6.39--1": { + "messageformat": "macOS စကá€șá€™á€»á€Źá€žá€á€œá€„á€ș á€€á€±á€Źá€œá€ș စေဏင့á€șဆိုငá€șှခနá€șသသို့ ဝငá€șလိုကá€șသေဏဥခါ တစá€șခါတစá€șရံ ဖဌစá€șပေါá€șတတá€șသည့á€ș á€á€á€á€Źá€”á€Ÿá€±á€Źá€„á€·á€șá€”á€Ÿá€±á€žá€™á€Ÿá€Żá€€á€­á€Ż ကျလနá€șုပá€șတို့ ပဌငá€șဆငá€șထဏသပါသညá€ș။" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "á€Ąá€–á€œá€Čá€·á€€á€±á€Źá€œá€șတလငá€ș လူတစá€șဩှ ပါဝငá€șá€œá€Źá€žá€±á€Źá€Ąá€á€« á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș ထလကá€șá€á€œá€Źá€žá€œá€Źá€žá€žá€±á€Źá€Ąá€á€« ပဌသသည့á€ș á€—á€źá€’á€źá€šá€­á€Żá€•á€Œá€€á€œá€€á€șá€™á€»á€Źá€žá€Ąá€á€œá€€á€ș á€Ąá€€á€°á€žá€Ąá€•á€Œá€±á€Źá€„á€șှ အနá€șá€”á€źá€™á€±á€žá€›á€Ÿá€„á€șှကို ကျလနá€șုပá€șတို့ ပဌငá€șဆငá€șထဏသပါသညá€ș။" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ယခုဥခါ ချကá€ș(တá€ș)ဆကá€șတငá€șမျဏသကို လျငá€șမဌနá€șá€…á€œá€Źá€á€„á€șကဌည့á€șရနá€ș á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș ထိုချကá€ș(တá€ș)မဟ မကဌည့á€șရသေသသေဏ á€…á€á€­á€Żá€›á€źá€™á€Ÿá€”á€șá€žá€™á€»á€Ÿá€€á€­á€Ż ကဌည့á€șá€›á€Ÿá€Żá€›á€”á€ș ချကá€ș(တá€ș)ခေါငá€șှစြှထá€Čမဟ ပရိုဖိုငá€șပုံ á€žá€­á€Żá€·á€™á€Ÿá€Żá€á€ș á€Ąá€–á€œá€Č့ရုပá€șပုံကို နဟိပá€șနိုငá€șá€•á€«á€•á€Œá€źá‹ ကျေသဇူသပါ {linkToGithub}။" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/nb/messages.json b/_locales/nb/messages.json index 31a0fa39c7..4ab1199ce3 100644 --- a/_locales/nb/messages.json +++ b/_locales/nb/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Databasefeil", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Det oppsto en feil med databasen. Du kan kopiere feilen og ta kontakt med Signals brukerstĂžtte for Ă„ fĂ„ hjelp. Hvis du trenger tilgang til Signal umiddelbart, kan du slette alle dataene og starte pĂ„ nytt.\n\nTa kontakt med brukerstĂžtte via {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { "messageformat": "Slett alle data og start pĂ„ nytt", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Vil du slette alle dataene permanent?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Alle meldingene og mediefilene dine slettes fra denne enheten for godt. Du kan bruke Signal pĂ„ denne enheten hvis du kobler den til brukeren din pĂ„ nytt. Ingen data fra mobilen din slettes.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Versjonen av databasen passer ikke sammen med denne versjonen av Signal. SĂžrg for at du bruker den nyeste versjonen av Signal pĂ„ datamaskinen din.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fil", @@ -300,6 +316,70 @@ "messageformat": "Samtaler", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Noe gikk galt med brukernavnet ditt. Det er ikke lenger tilknyttet kontoen din. Du kan prĂžve Ă„ angi det pĂ„ nytt, eller velge et annet brukernavn.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Fiks nĂ„", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Noe gikk galt med QR-koden og profillenken din. De er ikke lenger gyldige. Opprett en ny lenke for Ă„ dele profilen din med andre.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Fiks nĂ„", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Vis faner", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Skjul faner", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "En feil har oppstĂ„tt", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} uleste", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Merket som ulest", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Samtaler", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Samtaler", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Storyer", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Innstillinger", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Oppdater Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Tilbake", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Disse samtalene er arkiverte og dukker bare opp i innboksen hvis du fĂ„r nye meldinger.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ring allikevel", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Bli med likevel", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Fortsett samtale", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Vi endrer sikkerhetsnumrene.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "LĂŠr mer", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Forrige sikkerhetsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Neste sikkerhetsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Sikkerhetsnummerversjon {index,number} av {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Merk som bekreftet", @@ -663,33 +747,41 @@ "messageformat": "Fjern bekreftelse", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Hvis du vil sjekke ende-til-ende-krypteringen du har med {name}, sammenligner du tallene ovenfor med tallene pĂ„ enheten hens. Hen kan ogsĂ„ skanne koden din med enheten sin.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Les mer", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "For Ă„ sikre ende-til-ende-kryptering med {name} mĂ„ dere sjekke om fargekortet og koden ovenfor matcher det som kommer opp pĂ„ enheten hens. PrĂžv med en annen kombinasjon hvis de ikke matcher. Kun ett sett med fargekort og kode trenger Ă„ matche.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Hvis du vil sjekke ende-til-ende-krypteringen du har med {name}, sammenligner du tallene ovenfor med tallene pĂ„ enheten hens. Hen kan ogsĂ„ skanne koden din med enheten sin.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Endringer i sikkerhetsnummer", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "I overgangen til nye sikkerhetsfunksjoner i Signal har vi gjort et par endringer i sikkerhetsnumrene.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Match fargekortet med personen du skal chatte med, for Ă„ bekrefte sikkerhetsnumrene. PrĂžv med en annen kombinasjon hvis de ikke matcher. Kun ett sett med fargekort og kode trenger Ă„ matche.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Ønsker du hjelp?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "SkjĂžnner", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Samtalen vil fĂ„ et eget sikkerhetsnummer nĂ„r dere begynner Ă„ sende meldinger til hverandre.", @@ -1267,10 +1359,6 @@ "messageformat": "Vis nyere media", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Hvis du vil sjekke sikkerheten til ende-til-ende-krypteringen du har med {name}, sammenligner du tallene ovenfor med tallene pĂ„ enheten hens. Hen kan ogsĂ„ skanne QR-koden ovenfor.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Du har ikke utvekslet meldinger med denne kontakten ennĂ„. Sikkerhetsnummeret dere deler vil vĂŠre tilgjengelig etter den fĂžrste meldingen." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Slett", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Slett meldingene", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Vil du slette samtalen?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Vil du slette meldingene?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Denne samtalen slettes fra denne enheten.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Alle meldingene i denne samtalen slettes fra enheten. Du kan sĂžke etter samtalen selv om meldingene er slettet.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Forlat gruppen", @@ -1438,6 +1526,14 @@ "messageformat": "Meldingsloggene for begge samtalene er slĂ„tt sammen her.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} tilhĂžrer {conversationTitle}. Dere er begge medlemmer av {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} tilhĂžrer {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatyrbilde i sitert melding", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ring pĂ„ nytt", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Start samtale", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Bli med i samtale", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofonen ble slĂ„tt av pĂ„ grunn av antallet personer i samtalen", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Anropsvarsler", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Samtalen er full", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Bli med", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Start", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Samtalen er full", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera utilgjengelig", @@ -1621,10 +1725,6 @@ "messageformat": "Skru pĂ„ kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Demp", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon utilgjengelig", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "SlĂ„ pĂ„ mikrofon", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Del", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Presentasjon er deaktivert", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Avslutt presentasjonen", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ring", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Gruppen er for stor til Ă„ ringe deltakerne.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "SlĂ„ pĂ„ ringing", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "SlĂ„ av ringing", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "SlĂ„ pĂ„ ringing", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Flere muligheter", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Deg", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kameraet er skrudd av", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Vis sikkerhetsnummer", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Melding", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Vis sikkerhetsnummer", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Kunne ikke hente telefonnummeret. Sjekk internettilkoblingen og prĂžv igjen.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Meldinger kan kun redigeres de fĂžrste 3 timene etter at de ble sendt.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Meldinger kan kun redigeres de fĂžrste 24 timene etter at de ble sendt.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Denne meldingen ble slettet.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Vedlegget er for stort til Ă„ vises.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Enkelte vedlegg er for store til Ă„ vises.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Kunne ikke hente detaljene om pengegaven", "description": "Aria label for donation when we can't fetch the details." @@ -3073,7 +3197,7 @@ "description": "Shown in the calling keyboard shortcuts guide" }, "icu:Keyboard--start-audio-call": { - "messageformat": "Start taleanrop", + "messageformat": "Foreta et taleanrop", "description": "Shown in the calling keyboard shortcuts guide" }, "icu:Keyboard--start-video-call": { @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Kun med Signal Beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Kun Signal Beta-brukere kan redigere meldinger. Hvis du redigerer en melding, vil endringen kun vises for personer som bruker den nyeste versjonen av Signal Beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Rediger melding", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Hvis du redigerer en melding, vises endringen kun for personer som bruker den nyeste versjonen av Signal. De kan se at du redigerte en melding.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3373,13 +3505,21 @@ "description": "Shown in a notification body when Signal is minimized to tray" }, "icu:incomingAudioCall": { - "messageformat": "Innkommende taleanrop 
", + "messageformat": "Innkommende taleanrop 
", "description": "Shown in both the incoming call bar and notification for an incoming voice call" }, "icu:incomingVideoCall": { "messageformat": "Innkommende videoanrop 
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "UtgĂ„ende taleanrop", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "UtgĂ„ende videosamtale", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ringer deg", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Kobler til pĂ„ nytt 
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} person} other {{count,number} personer}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Taleanrop", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Avslutt", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Forlat gruppen", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon av", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon pĂ„", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Ringing pĂ„", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Ringing av", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Innstillinger", @@ -3468,13 +3668,25 @@ "messageformat": "Fullskjerm samtale", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Bytt til rutenettvisning", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Bytt visning", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Bytt til talervisning", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Rutenett", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Sidestolpe", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Den som snakker", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Visning oppdatert", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Forlat samtale", @@ -3549,7 +3761,7 @@ "description": "Label for muting the conversation" }, "icu:unmute": { - "messageformat": "SlĂ„ pĂ„ lyd", + "messageformat": "Vis varsler", "description": "Label for unmuting the conversation" }, "icu:muteExpirationLabelAlways": { @@ -3576,6 +3788,14 @@ "messageformat": "Greit", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Meldingen kan ikke redigeres", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Du kan kun gjĂžre {max,number} endringer i denne meldingen.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Beklager, den sgnl:// lenken ga ikke mening!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Brukernavn", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Noe gikk galt med brukernavnet ditt. Det er ikke lenger tilknyttet kontoen din.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Slett brukernavnet", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Opprett brukernavn", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-kode eller lenke", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Brukernavnet mĂ„ tilbakestilles", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Profillenken mĂ„ tilbakestilles", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Del brukernavnet ditt", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Slett brukernavnet", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Dette fjerner brukernavnet ditt, og andre brukere kan ta det. Er du helt sikker?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Brukernavnet fjernes, og QR-koden og profillenken din deaktiveres. Brukernavnet «{username}» kan brukes av andre. Er du sikker?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Du vil ikke lenger kunne dele eller se storyer. Oppdateringer av storyer som du nylig har delt, slettes ogsĂ„.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "SprĂ„k", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "SprĂ„k", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "SystemsprĂ„k", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "SĂžk etter sprĂ„k", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "«{searchTerm}» ga ingen resultater", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Velg", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Start Signal pĂ„ nytt for Ă„ ta i bruk", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Du mĂ„ Ă„pne appen pĂ„ nytt for Ă„ endre sprĂ„ket.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Omstart", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Oppdatering til versjon {version} er tilgjengelig", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Kunne ikke lagre innstillingene. PrĂžv igjen.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Melding", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Flere stilarter", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Tilbakestill", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Ferdig", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Farge pĂ„ brukernavnlenke, farge {index,number} av {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "QR-koden og profillenken din vil slutte Ă„ virke hvis du tilbakestiller QR-koden.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Lenken tilbakestilles ...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Det oppsto et problem med QR-koden og profillenken. Sjekk internettilkoblingen og prĂžv igjen.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Velg et brukernavn pĂ„ Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "redigert", + "messageformat": "Redigert", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Send pĂ„ nytt", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Flere funksjoner", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Samtaler", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nytt anrop", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nytt anrop", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Flere funksjoner", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "TĂžm anropsloggen", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Vil du slette anropsloggen?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Alle anropene fjernes fra listen permanent.", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Slett", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Anropslogg slettet", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Trykk for Ă„ se eller foreta et anrop", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "SĂžk", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Vis kun ubesvarte", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "SlĂ„ pĂ„/av", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ingen nylige samtaler. Kom i gang ved Ă„ ringe en venn.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "«{query}» ga ingen resultater", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Innkommende", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "utgĂ„ende", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ubesvart", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Gruppesamtale", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ingen nylige samtaler.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "«{query}» ga ingen resultater", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {UtgĂ„ende taleanrop} other {Innkommende taleanrop}}} Video {{direction, select, Outgoing {UtgĂ„ende videosamtale} other {Innkommende videosamtale}}} Group {{direction, select, Outgoing {UtgĂ„ende gruppeanrop} other {Innkommende gruppeanrop}}} other {{direction, select, Outgoing {UtgĂ„ende anrop} other {Innkommende anrop}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Tapt taleanrop} Video {Tapt videosamtale} Group {Ubesvart gruppeanrop} other {Tapt anrop}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Ubesvart taleanrop} Video {Ubesvart videosamtale} Group {Ubesvart gruppeanrop} other {Ubesvart anrop}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Avvist taleanrop} Video {Avvist videoanrop} Group {Avvist gruppeanrop} other {Avvist anrop}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} annen person skriver.} other {{count,number} andre personer skriver.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Siste nytt", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Noen smĂ„ justeringer, feilrettinger og ytelsesforbedringer. Takk for at du bruker Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Denne oppdateringen bestĂ„r av et par feilrettinger for lyd- og videosamtaler og et par smĂ„ dokumentasjonsoppdateringer (takk, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "NĂ„ kan du bytte sprĂ„k i Signal uten Ă„ endre sprĂ„ket pĂ„ enheten din (GĂ„ til Signal-innstillingene > Design > SprĂ„k)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Vi har endret noen av ikonene for gruppevarsler." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Det oppstod iblant forsinkelser nĂ„r man forsĂžkte Ă„ bli med i samtaler via enheter med macOS – dette er nĂ„ fikset." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Vi har fikset opp i animasjonene som dukker opp nĂ„r noen blir med i eller forlater en gruppesamtale." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "NĂ„ kan du trykke pĂ„ profilbildene eller gruppebildene for Ă„ gĂ„ til innstillingene og storyene i samtaler. Takk for hjelpen, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/nl/messages.json b/_locales/nl/messages.json index f12ae3adcb..ad21c28188 100644 --- a/_locales/nl/messages.json +++ b/_locales/nl/messages.json @@ -21,7 +21,7 @@ "description": "Shown as the title of the dialog that allows you to add a caption to a story" }, "icu:AddCaptionModal__placeholder": { - "messageformat": "Bericht verzenden", + "messageformat": "Bericht", "description": "Placeholder text for textarea when adding a caption/message (we don't know which yet so we default to message)" }, "icu:AddCaptionModal__submit-button": { @@ -57,7 +57,7 @@ "description": "Label of cancel button on voice note recording UI" }, "icu:RecordingComposer__send": { - "messageformat": "Uploaden", + "messageformat": "Versturen", "description": "Label of send button on voice note recording UI" }, "icu:GroupListItem__message-default": { @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Databankfout", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Er is een databasefout opgetreden. Je kunt de foutmelding kopiĂ«ren en contact opnemen met Signal-support om het probleem op te lossen. Als je Signal meteen wilt gebruiken, kun je je gegevens wissen en opnieuw opstarten.\n\nGa naar {link} voor contact met support", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Alle gegevens wissen en herstarten", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Gegevens wissen en opnieuw opstarten", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Alle gegevens definitief verwijderen?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Je gespreksgeschiedenis en media worden permanent van dit apparaat verwijderd. Je kunt Signal op dit apparaat gebruiken nadat je het opnieuw hebt gekoppeld. Er worden geen gegevens van je telefoon verwijderd.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "De versie van je database komt niet overeen met deze versie van Signal. Zorg ervoor dat je de nieuwste versie van Signal op je computer opent.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Bestand", @@ -300,8 +316,72 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Er is iets misgegaan met je gebruikersnaam, deze is niet meer aan je account toegewezen. Je kunt je gebruikersnaam opnieuw proberen in te stellen of een nieuwe kiezen.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Nu oplossen", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Er is iets misgegaan met je QR-code en gebruikersnaamlink, deze zijn niet langer geldig. Maak een nieuwe link om met anderen te delen.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Nu oplossen", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Tabbladen weergeven", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Tabbladen verbergen", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Er is een fout opgetreden", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ongelezen", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Gemarkeerd als ongelezen", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Oproepen", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Verhalen", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Instellingen", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal bijwerken", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profiel", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Terug", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { - "messageformat": "Deze chats worden gearchiveerd en zullen alleen opnieuw in de inbox verschijnen als je nieuwe berichten ontvangt.", + "messageformat": "Deze chats zijn gearchiveerd en zullen alleen opnieuw in de inbox verschijnen als je nieuwe berichten ontvangt.", "description": "Shown at the top of the archived conversations list in the left pane" }, "icu:noArchivedConversations": { @@ -313,7 +393,7 @@ "description": "Shown in menu for conversation, and moves conversation out of main conversation list" }, "icu:markUnread": { - "messageformat": "Voor mij markeren als ongelezen", + "messageformat": "Markeren als ongelezen", "description": "Shown in menu for conversation, and marks conversation as unread" }, "icu:ConversationHeader__menu__selectMessages": { @@ -361,7 +441,7 @@ "description": "Shown as the title in the confirmation modal for removing a system contact from the contact list" }, "icu:ContactListItem__remove-system--body": { - "messageformat": "Deze persoon is opgeslagen in de contactenlijst van je apparaat. Verwijder ze uit je Contacten op je mobiele apparaat en probeer het opnieuw.", + "messageformat": "Deze persoon is opgeslagen in de contactenlijst van je apparaat. Verwijder hem of haar uit je Contacten op je mobiele apparaat en probeer het opnieuw.", "description": "Shown as the body in the confirmation modal for removing a system contact from the contact list" }, "icu:moveConversationToInbox": { @@ -441,15 +521,15 @@ "description": "Message shown on the loading screen when we're changing database structure on first run of a new version" }, "icu:loadingMessages--other": { - "messageformat": "{daysAgo, plural, one {Berichten van 1 dag geleden laden...} other {Berichten van {daysAgo,number} dagen geleden laden...}}", + "messageformat": "{daysAgo, plural, one {Berichten van 1 dag geleden laden
} other {Berichten van {daysAgo,number} dagen geleden laden
}}", "description": "Message shown on the loading screen when we're catching up on the backlog of messages from day before yesterday and earlier" }, "icu:loadingMessages--yesterday": { - "messageformat": "Berichten van gisteren laden...", + "messageformat": "Berichten van gisteren laden
", "description": "Message shown on the loading screen when we're catching up on the backlog of messages from yesterday" }, "icu:loadingMessages--today": { - "messageformat": "Berichten van vandaag laden...", + "messageformat": "Berichten van vandaag laden
", "description": "Message shown on the loading screen when we're catching up on the backlog of messages from today" }, "icu:view": { @@ -457,7 +537,7 @@ "description": "Used as a label on a button allowing user to see more information" }, "icu:youLeftTheGroup": { - "messageformat": "Je bent niet langer lid van deze groep en je zult daarom geen nieuwe berichten zien.", + "messageformat": "Je bent niet langer lid van deze groep.", "description": "Displayed when a user can't send a message because they have left the group" }, "icu:invalidConversation": { @@ -576,6 +656,10 @@ "messageformat": "Toch bellen", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Toch deelnemen", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Oproep voortzetten", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -589,7 +673,7 @@ "description": "Shown in conversation banner when more than one group member's safety number has changed, but they were previously verified." }, "icu:debugLogExplanation": { - "messageformat": "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.", + "messageformat": "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 URL. Die URL 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" }, "icu:debugLogError": { @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Veiligheidsnummers worden bijgewerkt.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { - "messageformat": "Meer leren hierover", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "messageformat": "Meer informatie", + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Vorige veiligheidsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Volgende veiligheidsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Versie veiligheidsnummer, {index,number} van {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Als geverifieerd markeren", @@ -663,40 +747,48 @@ "messageformat": "Verificatie ongedaan maken", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Om end-to-end-versleuteling met {name} te verifiĂ«ren, vergelijk je bovenstaande nummers met het apparaat van je contact. Je contacten kunnen ook jouw QR-code scannen met hun apparaat.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Meer informatie", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Om end-to-end-versleuteling met {name} te verifiĂ«ren, vergelijk je bovenstaande kleurenkaart met de nummers op de kaart van je contact. Zijn de nummers niet gelijk, probeer dan een andere combinatie van veiligheidsnummers. Er hoeft maar één paar te matchen.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Om end-to-end-versleuteling met {name} te verifiĂ«ren, vergelijk je bovenstaande nummers met het apparaat van je contact. Je contacten kunnen ook jouw code scannen met hun apparaat.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Veranderingen in veiligheidsnummers", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Veiligheidsnummers worden gedurende een overgangsperiode bijgewerkt als voorbereiding op toekomstige privacyfuncties in Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Om veiligheidsnummers te verifiĂ«ren, vergelijk je de kleurenkaart met de kaart op het apparaat van je contactpersoon. Zijn de nummers niet gelijk, probeer dan een andere combinatie van veiligheidsnummers. Er hoeft maar één paar te matchen.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Hulp nodig?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Begrepen", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Er wordt een veiligheidsnummer aangemaakt met deze persoon nadat je berichten hebt uitgewisseld.", "description": "Body of SafetyNumberNotReady modal" }, "icu:SafetyNumberNotReady__learn-more": { - "messageformat": "Meer leren hierover", + "messageformat": "Meer informatie", "description": "Text of 'Learn more' button of SafetyNumberNotReady modal" }, "icu:isVerified": { @@ -777,7 +869,7 @@ "description": "Shown in toast when user attempts to send .exe file, for example" }, "icu:loadingPreview": { - "messageformat": "Voorbeeldafbeelding aan het laden 
", + "messageformat": "Linkvoorbeeld aan het laden
", "description": "Shown while Signal Desktop is fetching metadata for a url in composition area" }, "icu:stagedPreviewThumbnail": { @@ -828,7 +920,7 @@ "description": "Displayed when the desktop client cannot connect to the server." }, "icu:connecting": { - "messageformat": "Aan het verbinden 
", + "messageformat": "Aan het verbinden
", "description": "Displayed when the desktop client is currently connecting to the server." }, "icu:connect": { @@ -860,7 +952,7 @@ "description": "View menu item to force the app to update download and install" }, "icu:helpMenuShowKeyboardShortcuts": { - "messageformat": "Toetsenbord-snelkoppelingen weergeven", + "messageformat": "Sneltoetsen weergeven", "description": "Item under the help menu, pops up a screen showing the application's keyboard shortcuts" }, "icu:contactUs": { @@ -932,7 +1024,7 @@ "description": "Shown in the search box before text is entered when searching in a specific conversation" }, "icu:noSearchResults": { - "messageformat": "Geen resultaten voor “{searchTerm}”", + "messageformat": "Geen resultaten voor “{searchTerm}”", "description": "Shown in the search left pane when no results were found" }, "icu:noSearchResults--sms-only": { @@ -991,7 +1083,7 @@ "description": "Used in the alt tag for the image avatar of a contact" }, "icu:sendMessageToContact": { - "messageformat": "Bericht zenden", + "messageformat": "Bericht sturen", "description": "Shown when you are sent a contact and that contact has a signal account" }, "icu:home": { @@ -1155,7 +1247,7 @@ "description": "Shown if a general error happened while trying to install update package and manual update is required" }, "icu:readOnlyVolume": { - "messageformat": "Signal-desktop bevind zich waarschijnlijk in een MacOS quarantaine, waardoor het niet automatisch kan bijwerken. Probeer de directory {app} met Finder naar {folder} te verplaatsen.", + "messageformat": "Signal-desktop bevind zich waarschijnlijk in een MacOS quarantaine, waardoor het niet automatisch kan bijwerken. Probeer de directory {app} met Finder naar {folder} te verplaatsen.", "description": "Shown on MacOS if running on a read-only volume and we cannot update" }, "icu:ok": { @@ -1267,10 +1359,6 @@ "messageformat": "Recente media weergeven", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Om de veiligheid van je end-to-end-versleuteling met {name} te verifiĂ«ren, vergelijk je de bovenstaande nummers met die op het apparaat van je contact. Jouw contacten kunnen ook de bovenstaande QR-code scannen.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Je hebt nog geen berichten uitgewisseld met deze contactpersoon. Je veiligheidsnummer met hem zal beschikbaar zijn na het eerste bericht." }, @@ -1334,17 +1422,17 @@ "messageformat": "Bericht­details", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Wissen", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Berichten wissen", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Chat verwijderen?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Berichten wissen?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Deze chat wordt alleen op dit apparaat verwijderd.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Berichten in deze chat worden van dit apparaat verwijderd. Je kunt nog steeds naar deze chat zoeken nadat je berichten hebt verwijderd.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Groep verlaten", @@ -1355,7 +1443,7 @@ "description": "Conversation Header > Leave Group Action > Leave Group Confirmation Modal > Title" }, "icu:ConversationHeader__LeaveGroupConfirmation__description": { - "messageformat": "Je kunt in dit groepsgesprek niet langer berichten verzenden of ontvangen.", + "messageformat": "Je zult in deze groep niet langer berichten kunnen verzenden of ontvangen.", "description": "Conversation Header > Leave Group Action > Leave Group Confirmation Modal > Description" }, "icu:ConversationHeader__LeaveGroupConfirmation__confirmButton": { @@ -1403,7 +1491,7 @@ "description": "Shown on explainer dialog available from delivery issue timeline events" }, "icu:DeliveryIssue--summary": { - "messageformat": "Een bericht, media, sticker, emoji-reactie, of een bevestiging dat een bericht gelezen is van {sender} kan niet aan jou worden afgeleverd. Het kan zijn dat hij of zij iets probeerde naar je te verzenden in een één-op-één-gesprek of in een groepsgesprek.", + "messageformat": "Een bericht, media, sticker, emoji-reactie, of leesbevestiging van {sender} kon niet aan jou worden afgeleverd. Het kan zijn dat hij of zij iets naar je probeerde te verzenden in een één-op-één-gesprek of in een groepsgesprek.", "description": "Shown on explainer dialog available from delivery issue timeline events in 1:1 conversations" }, "icu:DeliveryIssue--summary--group": { @@ -1423,7 +1511,7 @@ "description": "Shown when we've discovered that two local conversations are the same remote account in an unusual way, but we have the phone number for the old conversation" }, "icu:ConversationMerge--notification--no-title": { - "messageformat": "Je berichtengeschiedenis met {conversationTitle} en een andere chat met hen zijn samengevoegd.", + "messageformat": "Je berichtengeschiedenis met {conversationTitle} en een andere chat met hem of haar zijn samengevoegd.", "description": "Shown when we've discovered that two local conversations are the same remote account in an unusual way, but we don't have the title for the old conversation" }, "icu:ConversationMerge--learn-more": { @@ -1438,6 +1526,14 @@ "messageformat": "Je berichtengeschiedenis voor beide chats is hier samengevoegd.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} is van {conversationTitle}. Jullie zijn allebei lid van {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} is van {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatuur van afbeelding uit aangehaald bericht", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1487,7 +1583,7 @@ "description": "The menu option shown in Signal iOS to add a new linked device" }, "icu:Install__learn-more": { - "messageformat": "Meer leren hierover", + "messageformat": "Meer informatie", "description": "Button text for learn more button during error screen" }, "icu:Install__scan-this-code": { @@ -1585,10 +1681,6 @@ "messageformat": "Opnieuw bellen", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Oproep beginnen", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Aan oproep deelnemen", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Je microfoon is gedempt vanwege het aantal deelnemers aan deze oproep", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Oproepmeldingen", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "De oproep is vol", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Camera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Deelnemen", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Beginnen", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Oproep vol", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Camera uitgeschakeld", @@ -1621,10 +1725,6 @@ "messageformat": "Camera inschakelen", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Dempen", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microfoon uitgeschakeld", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Microfoon niet langer dempen", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Scherm laten zien", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Scherm laten zien is uitgeschakeld", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Stoppen met scherm laten zien", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Bellen", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "De groep is te groot om de leden te bellen.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,32 +1761,52 @@ "messageformat": "Laat een beltoon horen als ik gebeld wordt", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Bellen uitschakelen", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Bellen inschakelen", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Meer opties", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Jij", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Je camera staat uit", "description": "Label in the calling lobby indicating that your camera is off" }, "icu:calling__pre-call-info--empty-group": { - "messageformat": "Er is niemand in de groepsoproep. Klik op ‘Oproep beginnen’ om een oproep te beginnen.", + "messageformat": "Er is niemand hier", "description": "Shown in the calling lobby to describe who is in the call" }, "icu:calling__pre-call-info--1-person-in-call": { - "messageformat": "{first} is aanwezig in de oproep. Klik op ‘Aan oproep deelnemen’ om zelf deel te nemen.", + "messageformat": "{first} is aanwezig in de oproep.", "description": "Shown in the calling lobby to describe who is in the call" }, "icu:calling__pre-call-info--another-device-in-call": { - "messageformat": "Een van je andere apparaten neemt deel aan deze oproep. Klik op ‘Aan oproep deelnemen’ om ook vanaf dit apparaat deel te nemen.", + "messageformat": "Een van je andere apparaten neemt deel aan deze oproep.", "description": "Shown in the calling lobby to describe when it is just you" }, "icu:calling__pre-call-info--2-people-in-call": { - "messageformat": "{first} en {second} zijn aanwezig in deze oproep. Klik op ‘Aan oproep deelnemen’ om zelf deel te nemen.", + "messageformat": "{first} en {second} zijn aanwezig in deze oproep.", "description": "Shown in the calling lobby to describe who is in the call" }, "icu:calling__pre-call-info--3-people-in-call": { - "messageformat": "{first}, {second} en {third} zijn aanwezig in deze oproep. Klik op ‘Aan oproep deelnemen’ om zelf deel te nemen.", + "messageformat": "{first}, {second} en {third} zijn aanwezig in deze oproep.", "description": "Shown in the calling lobby to describe who is in the call" }, "icu:calling__pre-call-info--many-people-in-call": { - "messageformat": "{first}, {second} en {others} anderen zijn aanwezig in deze oproep. Klik op ‘Aan oproep deelnemen’ om zelf deel te nemen.", + "messageformat": "{first}, {second} en {others} anderen zijn aanwezig in deze oproep.", "description": "Shown in the calling lobby to describe who is in the call" }, "icu:calling__pre-call-info--will-ring-1": { @@ -1730,7 +1842,7 @@ "description": "Shown in the calling lobby to describe who will be notified" }, "icu:calling__in-this-call--zero": { - "messageformat": "Er is niemand in de groepsoproep. Klik op ‘Oproep beginnen’ om een oproep te beginnen.", + "messageformat": "Er is niemand hier", "description": "Shown in the participants list to describe how many people are in the call" }, "icu:calling__in-this-call--one": { @@ -1826,11 +1938,11 @@ "description": "Header for permissions section of settings" }, "icu:mediaPermissionsDescription": { - "messageformat": "Ik geef de Signal-app toestemming om mijn microfoon te gebruiken", + "messageformat": "Toegang tot de microfoon toestaan", "description": "Description of the media permission description" }, "icu:mediaCameraPermissionsDescription": { - "messageformat": "Ik geef de Signal-app toestemming om mijn camera te gebruiken", + "messageformat": "Toegang tot de camera toestaan", "description": "Description of the media permission description" }, "icu:general": { @@ -1952,7 +2064,7 @@ "description": "Shown on a message which was edited if the edit wasn't successfully sent to anyone" }, "icu:sendPaused": { - "messageformat": "Verzending is gepauzeerd", + "messageformat": "Verzenden is gepauzeerd", "description": "Shown on outgoing message if it cannot be sent immediately" }, "icu:partiallySent": { @@ -2008,7 +2120,7 @@ "description": "Label for a button that syncs contacts and groups from your phone" }, "icu:syncing": { - "messageformat": "Bezig met importeren 
", + "messageformat": "Bezig met importeren
", "description": "Label for a disabled sync button while sync is in progress." }, "icu:syncFailed": { @@ -2060,19 +2172,19 @@ "description": "Brief message shown when trying to message a blocked group" }, "icu:youChangedTheTimer": { - "messageformat": "Je hebt de tijdsspanne voor verlopende berichten op {time} ingesteld.", + "messageformat": "Je hebt de timer voor verdwijnende berichten op {time} ingesteld.", "description": "Message displayed when you change the message expiration timer in a conversation." }, "icu:timerSetOnSync": { - "messageformat": "De tijdsspanne voor verlopende berichten is bijgewerkt naar {time}.", + "messageformat": "De timer voor verdwijnende berichten is bijgewerkt naar {time}.", "description": "Message displayed when timer is set on initial link of desktop device." }, "icu:timerSetByMember": { - "messageformat": "Een groepslid heeft de tijdsspanne voor verlopende berichten op {time} ingesteld.", + "messageformat": "Een groepslid heeft de timer voor verdwijnende berichten op {time} ingesteld.", "description": "Message displayed when timer is by an unknown group member." }, "icu:theyChangedTheTimer": { - "messageformat": "{name} heeft de tijdsspanne voor verlopende berichten op {time} ingesteld.", + "messageformat": "{name} heeft de timer voor verdwijnende berichten op {time} ingesteld.", "description": "Message displayed when someone else changes the message expiration timer in a conversation." }, "icu:disappearingMessages__off": { @@ -2080,27 +2192,27 @@ "description": "Label for option to turn off message expiration in the timer menu" }, "icu:disappearingMessages": { - "messageformat": "Verlopende berichten", + "messageformat": "Verdwijnende berichten", "description": "Conversation menu option to enable disappearing messages. Title of the settings section for Disappearing Messages. Label of the disappearing timer select in group creation flow" }, "icu:disappearingMessagesDisabled": { - "messageformat": "Verlopende berichten zijn uitgeschakeld", + "messageformat": "Verdwijnende berichten zijn uitgeschakeld", "description": "Displayed in the left pane when the timer is turned off" }, "icu:disappearingMessagesDisabledByMember": { - "messageformat": "Een groepslid heeft verlopende berichten uitgeschakeld.", + "messageformat": "Een groepslid heeft verdwijnende berichten uitgeschakeld.", "description": "Displayed in the left pane when the timer is turned off" }, "icu:disabledDisappearingMessages": { - "messageformat": "{name} heeft verlopende berichten uitgeschakeld.", + "messageformat": "{name} heeft verdwijnende berichten uitgeschakeld.", "description": "Displayed in the conversation list when the timer is turned off" }, "icu:youDisabledDisappearingMessages": { - "messageformat": "Je hebt verlopende berichten uitgeschakeld.", + "messageformat": "Je hebt verdwijnende berichten uitgeschakeld.", "description": "Displayed in the conversation list when the timer is turned off" }, "icu:timerSetTo": { - "messageformat": "Tijdsspanne ingesteld op {time}", + "messageformat": "De timer voor verdwijnende berichten is op {time} ingesteld", "description": "Displayed in the conversation list when the timer is updated by some automatic action, or in the left pane" }, "icu:audioNotificationDescription": { @@ -2120,11 +2232,11 @@ "description": "Description for incoming calls setting" }, "icu:contactChangedProfileName": { - "messageformat": "{sender} heeft zijn of haar profielnaam van {oldProfile} naar {newProfile} gewijzigd.", + "messageformat": "{sender} heeft zijn of haar profielnaam van “{oldProfile}” naar “{newProfile}” gewijzigd.", "description": "Description for incoming calls setting" }, "icu:changedProfileName": { - "messageformat": "{oldProfile} wijzigde zijn of haar profielnaam naar {newProfile}.", + "messageformat": "{oldProfile} heeft zijn of haar profielnaam naar “{newProfile}” gewijzigd.", "description": "Shown when a contact not in your address book changes their profile name" }, "icu:SafetyNumberModal__title": { @@ -2136,7 +2248,7 @@ "description": "A notification shown in the conversation when a contact reinstalls" }, "icu:safetyNumberChanges": { - "messageformat": "Veiligheidsnummer veranderingen", + "messageformat": "Veranderingen in veiligheidsnummer", "description": "Title for safety number changed modal" }, "icu:safetyNumberChangedGroup": { @@ -2147,6 +2259,10 @@ "messageformat": "Veiligheidsnummer weergeven", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Bericht versturen", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Veiligheidsnummer weergeven", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2168,7 +2284,7 @@ "description": "Label text for dark theme" }, "icu:themeSystem": { - "messageformat": "Systeemstandaard volgen", + "messageformat": "Systeemstandaard", "description": "Label text for system theme" }, "icu:noteToSelf": { @@ -2176,7 +2292,7 @@ "description": "Name for the conversation with your own phone number" }, "icu:noteToSelfHero": { - "messageformat": "Je kunt in deze chat notities voor jezelf achterlaten. Voeg teksten toe en lees ze terug vanaf al je gekoppelde apparaten. Alle nieuwe notities worden gesynchroniseerd met de apparaten die gekoppeld zijn met je account.", + "messageformat": "Je kunt in deze chat notities voor jezelf achterlaten. Alle nieuwe notities worden gesynchroniseerd met apparaten die gekoppeld zijn met je account.", "description": "Description for the Note to Self conversation" }, "icu:notificationDrawAttention": { @@ -2235,8 +2351,8 @@ "messageformat": "Het ophalen van het telefoonnummer is mislukt. Ga na dat je apparaat met het internet is verbonden en probeer het opnieuw.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Bewerkingen kunnen alleen worden toegepast binnen 3 uur vanaf het moment dat je dit bericht hebt verstuurd.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Berichten kunnen alleen binnen 24 uur na verzenden bewerkt worden.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2252,7 +2368,7 @@ "description": "Shown in dialog if phone number is not valid." }, "icu:chooseGroupMembers__title": { - "messageformat": "Groepsleden kiezen", + "messageformat": "Kies leden", "description": "The title for the 'choose group members' left pane screen" }, "icu:chooseGroupMembers__back-button": { @@ -2284,7 +2400,7 @@ "description": "Shown in the alert when you add the maximum recommended number of group members" }, "icu:setGroupMetadata__title": { - "messageformat": "Geef dit groepsgesprek een naam", + "messageformat": "Geef deze groep een naam", "description": "The title for the 'set group metadata' left pane screen" }, "icu:setGroupMetadata__back-button": { @@ -2480,6 +2596,14 @@ "messageformat": "Dit bericht is gewist.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Bijlage te groot om weer te geven.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Sommige bijlagen zijn te groot om weer te geven.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Donatiegegevens kunnen niet worden opgehaald", "description": "Aria label for donation when we can't fetch the details." @@ -2489,7 +2613,7 @@ "description": "Shown in a message's bubble when you've received a donation badge from a contact" }, "icu:message--donation--unopened--outgoing": { - "messageformat": "Tik op dit bericht op mobiel om je donatie te bekijken", + "messageformat": "Tik op dit bericht op je mobiel om je donatie te bekijken", "description": "Shown in a message's bubble when you've sent a donation badge to a contact." }, "icu:message--donation--unopened--label": { @@ -2653,7 +2777,7 @@ "description": "Shown in the sticker picker when one or more stickers could not be downloaded." }, "icu:stickers--StickerPicker--DownloadPending": { - "messageformat": "Stickerpakket wordt geĂŻnstalleerd 
", + "messageformat": "Stickerpakket wordt geĂŻnstalleerd
", "description": "Shown in the sticker picker when one or more stickers are still downloading." }, "icu:stickers--StickerPicker--Empty": { @@ -2772,7 +2896,7 @@ "messageformat": "Je hebt een bericht ontvangen van {contact} die niet kan worden verwerkt of niet kan worden weergegeven omdat het gebruik maakt van een nieuwe functie van Signal." }, "icu:Message--unsupported-message-ask-to-resend": { - "messageformat": "Nu je een actuele versie van Signal gebruikt kun je {contact} vragen om dit bericht opnieuw te verzenden ." + "messageformat": "Nu je een actuele versie van Signal gebruikt kun je {contact} vragen om dit bericht opnieuw te verzenden." }, "icu:Message--from-me-unsupported-message": { "messageformat": "Een van je apparaten heeft een bericht verstuurd welke niet kan worden verwerkt of niet kan worden weergegeven omdat dat bericht gebruik maakt van een nieuwe funcie van Signal." @@ -2937,7 +3061,7 @@ "description": "Shown in the shortcuts guide" }, "icu:Keyboard--remove-draft-link-preview": { - "messageformat": "Concept-voorbeeldafbeelding verwijderen", + "messageformat": "Concept-linkvoorbeeld verwijderen", "description": "Shown in the shortcuts guide" }, "icu:Keyboard--remove-draft-attachments": { @@ -2981,7 +3105,7 @@ "description": "Expresses that 1, 2, 3, up to 9 are available shortcut keys" }, "icu:Keyboard--header": { - "messageformat": "Toetsenbord-snelkoppelingen", + "messageformat": "Sneltoetsen", "description": "Title header of the keyboard shortcuts guide" }, "icu:Keyboard--navigation-header": { @@ -3073,7 +3197,7 @@ "description": "Shown in the calling keyboard shortcuts guide" }, "icu:Keyboard--start-audio-call": { - "messageformat": "Spraakgesprek beginnen?", + "messageformat": "Spraakoproep beginnen?", "description": "Shown in the calling keyboard shortcuts guide" }, "icu:Keyboard--start-video-call": { @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Alleen Signal-bĂšta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Berichten bewerken is alleen beschikbaar voor gebruikers van Signal-bĂšta. Als je een bericht bewerkt, is dat alleen zichtbaar voor mensen met de laatste versie van Signal-bĂšta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Bericht bewerken", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Als je een bericht bewerkt, is dat alleen zichtbaar voor mensen met de laatste versie van Signal. Ze kunnen zien dat je een bericht hebt bewerkt.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3309,7 +3441,7 @@ "description": "Shown to indicate this user is not a member of any groups" }, "icu:no-groups-in-common-warning": { - "messageformat": "Deze persoon is een onbekende, je zit zelfs niet in een groepsgesprek met deze persoon. Overweeg daarom zorgvuldig of je dit gespreksverzoek wilt aanvaarden.", + "messageformat": "Je hebt geen gemeenschappelijke groepen met deze persoon. Beoordeel dit gespreksverzoek zorgvuldig.", "description": "When a user has no common groups, show this warning" }, "icu:acceptCall": { @@ -3345,7 +3477,7 @@ "description": "Shown in conversation history when you missed an incoming voice call" }, "icu:missedIncomingVideoCall": { - "messageformat": "Video-oproep gemist", + "messageformat": "Gemiste video-oproep", "description": "Shown in conversation history when you missed an incoming video call" }, "icu:acceptedOutgoingAudioCall": { @@ -3373,13 +3505,21 @@ "description": "Shown in a notification body when Signal is minimized to tray" }, "icu:incomingAudioCall": { - "messageformat": "Inkomend spraakgesprek...", + "messageformat": "Inkomende spraakoproep
", "description": "Shown in both the incoming call bar and notification for an incoming voice call" }, "icu:incomingVideoCall": { - "messageformat": "Inkomende video-oproep 
", + "messageformat": "Inkomende video-oproep
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Uitgaande spraakoproep", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Uitgaande video-oproep", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} belt je", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3401,7 +3541,7 @@ "description": "Shown in the incoming call bar when someone is ringing you for a group call" }, "icu:outgoingCallRinging": { - "messageformat": "Gaat over 
", + "messageformat": "Gaat over
", "description": "Shown in the call screen when placing an outgoing call that is now ringing" }, "icu:makeOutgoingCall": { @@ -3421,12 +3561,72 @@ "description": "Shown when a call is rejected because the other party hasn't approved the message/call request" }, "icu:callReconnecting": { - "messageformat": "Opnieuw verbinden 
", + "messageformat": "Opnieuw verbinden
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal-oproep {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} persoon} other {{count,number} personen}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio-oproep", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "BeĂ«indigen", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Verlaten", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Microfoon uit", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Microfoon aan", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Bellen aan", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Bellen uit", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Instellingen", @@ -3468,13 +3668,25 @@ "messageformat": "Oproep volledig scherm laten innemen", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Overschakelen naar rasterweergave", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Weergave wijzigen", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Overschakelen naar huidige-spreker-weergave", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Rasterweergave", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Zijbalkweergave", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Sprekerweergave", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Weergave bijgewerkt", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Oproep verlaten", @@ -3576,6 +3788,14 @@ "messageformat": "OkĂ©", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Kan bericht niet bewerken", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Dit bericht kan maximaal {max,number} keer bewerkt worden.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Sorry, die sgnl:// link klopt niet.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -3637,7 +3857,7 @@ "description": "Shown when you click on a group link to confirm, if it requires admin approval" }, "icu:GroupV2--join--join-button": { - "messageformat": "Aan oproep deelnemen", + "messageformat": "Deelnemen", "description": "The button to join the group" }, "icu:GroupV2--join--request-to-join-button": { @@ -3689,7 +3909,7 @@ "description": "Label for describing the general non-privileged members of a group" }, "icu:updating": { - "messageformat": "Aan het bijwerken 
", + "messageformat": "Aan het bijwerken
", "description": "Shown along with a spinner when an update operation takes longer than one second" }, "icu:GroupV2--create--you": { @@ -3801,27 +4021,27 @@ "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--disabled--you": { - "messageformat": "Je hebt de beheerderstoestemming-vereiste om via de groepslink lid te mogen worden uitgeschakeld.", + "messageformat": "Je hebt beheerdersgoedkeuring van nieuwe leden uitgeschakeld voor de groepslink.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--disabled--other": { - "messageformat": "{adminName} heeft de beheerderstoestemming-vereiste om via de groepslink lid te mogen worden van de groep uitgeschakeld.", + "messageformat": "{adminName} heeft beheerdersgoedkeuring van nieuwe leden uitgeschakeld voor de groepslink.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--disabled--unknown": { - "messageformat": "De beheerderstoestemming-vereiste om via de groepslink lid te mogen worden van de groep is uitgeschakeld.", + "messageformat": "Beheerdersgoedkeuring van nieuwe leden is uitgeschakeld voor de groepslink.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--enabled--you": { - "messageformat": "Je hebt de beheerderstoestemming-vereiste om via de groepslink lid te mogen worden van de groep ingeschakeld.", + "messageformat": "Je hebt beheerdersgoedkeuring van nieuwe leden ingeschakeld voor de groepslink.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--enabled--other": { - "messageformat": "{adminName} heeft de beheerderstoestemming-vereiste voor personen die lid willen worden via de groepslink ingeschakeld.", + "messageformat": "{adminName} heeft beheerdersgoedkeuring van nieuwe leden ingeschakeld voor de groepslink.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--enabled--unknown": { - "messageformat": "De beheerderstoestemming-vereiste om via de groepslink lid te mogen worden van de groep is ingeschakeld.", + "messageformat": "Beheerdersgoedkeuring van nieuwe leden is ingeschakeld voor de groepslink.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--member-add--invited--you": { @@ -4125,7 +4345,7 @@ "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--admin-approval-remove-one--other--own": { - "messageformat": "{joinerName} heeft zijn of haar verzoek om lid te worden van de groep ingetrokken.", + "messageformat": "{joinerName} heeft het verzoek om lid te worden van de groep ingetrokken.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--admin-approval-remove-one--other--other": { @@ -4141,27 +4361,27 @@ "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--disabled--you": { - "messageformat": "Je hebt de groepslink ingeschakeld zonder beheerderstoestemming-vereiste om lid te mogen worden.", + "messageformat": "Je hebt de groepslink zonder beheerdersgoedkeuring van nieuwe leden ingeschakeld.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--disabled--other": { - "messageformat": "{adminName} heeft de groepslink ingeschakeld zonder beheerderstoestemming-vereiste om lid te mogen worden.", + "messageformat": "{adminName} heeft de groepslink zonder beheerdersgoedkeuring van nieuwe leden ingeschakeld.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--disabled--unknown": { - "messageformat": "De groepslink is ingeschakeld zonder beheerderstoestemming-vereiste om lid te mogen worden.", + "messageformat": "De groepslink zonder beheerdersgoedkeuring van nieuwe leden is ingeschakeld.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--enabled--you": { - "messageformat": "Je hebt de groepslink ingeschakeld met beheerderstoestemming-vereiste om lid te mogen worden ook ingeschakeld.", + "messageformat": "Je hebt de groepslink met beheerdersgoedkeuring van nieuwe leden ingeschakeld.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--enabled--other": { - "messageformat": "{adminName} heeft de groepslink ingeschakeld met beheerderstoestemming-vereiste om lid te mogen worden ook ingeschakeld.", + "messageformat": "{adminName} heeft de groepslink met beheerdersgoedkeuring van nieuwe leden ingeschakeld.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--enabled--unknown": { - "messageformat": "De groepslink is ingeschakeld met beheerderstoestemming-vereiste om lid te mogen worden ook ingeschakeld.", + "messageformat": "De groepslink met beheerdersgoedkeuring van nieuwe leden is ingeschakeld.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-remove--you": { @@ -4429,7 +4649,7 @@ "description": "This is a button in the conversation context menu to show the chat color editor" }, "icu:showConversationDetails": { - "messageformat": "Groepsgesprek-instellingen", + "messageformat": "Groepsinstellingen", "description": "This is a button in the conversation context menu to show group settings" }, "icu:showConversationDetails--direct": { @@ -4445,15 +4665,15 @@ "description": "This is the label for the group link management panel" }, "icu:ConversationDetails--disappearing-messages-label": { - "messageformat": "Verlopende berichten", + "messageformat": "Verdwijnende berichten", "description": "This is the label for the disappearing messages setting panel" }, "icu:ConversationDetails--disappearing-messages-info--group": { - "messageformat": "Nieuwe berichten in dit gesprek zullen voor iedereen worden gewist nadat de ingestelde tijdspanne is verlopen. De tijdspanne begint voor iedere persoon individueel pas te lopen vanaf het moment dat hij of zij het bericht heeft gezien. — Gebruik verlopende berichten niet ter beveiliging, want Signal kan niet garanderen dat berichten op het apparaat van een ander ook daadwerkelijk worden gewist.", + "messageformat": "Indien ingeschakeld, worden nieuwe berichten die in deze groep zijn verstuurd en ontvangen gewist nadat ze zijn gezien en de timer is afgelopen.", "description": "This is the info about the disappearing messages setting, in groups" }, "icu:ConversationDetails--disappearing-messages-info--direct": { - "messageformat": "Als dit aanstaat, verdwijnen berichten die in deze individuele chat zijn verstuurd en ontvangen nadat ze zijn gezien.", + "messageformat": "Indien ingeschakeld, worden nieuwe berichten die in deze chat zijn verstuurd en ontvangen gewist nadat ze zijn gezien en de timer is afgelopen.", "description": "This is the info about the disappearing messages setting, for direct conversations" }, "icu:ConversationDetails--notifications": { @@ -4465,7 +4685,7 @@ "description": "This is the label for the 'who can edit the group' panel" }, "icu:ConversationDetails--group-info-info": { - "messageformat": "Kies wie de groepsnaam, -afbeelding, -omschrijving en de tijdspanne voor verlopende berichten kan bewerken.", + "messageformat": "Kies wie de groepsnaam, -afbeelding, -omschrijving en de timer voor verdwijnende berichten kan bewerken.", "description": "This is the additional info for the 'who can edit the group' panel" }, "icu:ConversationDetails--add-members-label": { @@ -4509,7 +4729,7 @@ "description": "This is the modal title for confirming leaving a group" }, "icu:ConversationDetailsActions--leave-group-modal-content": { - "messageformat": "Je zult in dit groepsgesprek niet langer berichten kunnen verzenden of ontvangen.", + "messageformat": "Je zult in deze groep niet langer berichten kunnen verzenden of ontvangen.", "description": "This is the modal content for confirming leaving a group" }, "icu:ConversationDetailsActions--leave-group-modal-confirm": { @@ -4569,7 +4789,7 @@ "description": "Title of the groups-in-common panel, in the contact details" }, "icu:ConversationDetailsGroups--title--with-zero-groups-in-common": { - "messageformat": "Geen andere gemeenschappelijke groepen", + "messageformat": "Geen gemeenschappelijke groepen", "description": "Title of the groups-in-common panel, in the contact details, with zero groups in common" }, "icu:ConversationDetailsGroups--add-to-group": { @@ -4605,7 +4825,7 @@ "description": "This lets users share their group link" }, "icu:GroupLinkManagement--confirm-reset": { - "messageformat": "Weet je zeker dat je de groepslink wilt vernieuwen? Als je de link vernieuwt zullen mensen niet langer lid kunnen worden via de huidige link.", + "messageformat": "Weet je zeker dat je de groepslink wilt vernieuwen? Als je de link vernieuwt kunnen mensen niet langer lid worden via de huidige link.", "description": "Shown in the confirmation dialog when an admin is about to reset the group link" }, "icu:GroupLinkManagement--reset": { @@ -4613,11 +4833,11 @@ "description": "This lets users generate a new group link" }, "icu:GroupLinkManagement--approve-label": { - "messageformat": "Beheerderstoestemming vereisen", + "messageformat": "Nieuwe leden goedkeuren", "description": "Title for the approve new members select area" }, "icu:GroupLinkManagement--approve-info": { - "messageformat": "Vereis voor iedere persoon die via de groepslink lid wil worden eerst toestemming van een beheerder", + "messageformat": "Vereis voor iedere persoon die via de groepslink lid wil worden eerst goedkeuring van een beheerder", "description": "Description for the approve new members select area" }, "icu:PendingInvites--tab-requests": { @@ -4657,7 +4877,7 @@ "description": "This is the label for the number of members someone has invited" }, "icu:PendingInvites--revoke-for-label": { - "messageformat": "Groepslidmaatschap-uitnodiging intrekken", + "messageformat": "Groepsuitnodiging intrekken", "description": "This is aria label for revoking a group invite icon" }, "icu:PendingInvites--revoke-for": { @@ -4733,7 +4953,7 @@ "description": "within note to self conversation > delete selected messages > confirmation modal > description" }, "icu:DeleteMessagesModal--deleteForMe": { - "messageformat": "Voor mij verwijderen", + "messageformat": "Voor mij wissen", "description": "delete selected messages > confirmation modal > delete for me" }, "icu:DeleteMessagesModal--deleteFromThisDevice": { @@ -4741,7 +4961,7 @@ "description": "within note to self conversation > delete selected messages > confirmation modal > delete from this device (same as delete for me)" }, "icu:DeleteMessagesModal--deleteForEveryone": { - "messageformat": "Verwijderen voor iedereen", + "messageformat": "Wissen voor iedereen", "description": "delete selected messages > confirmation modal > delete for everyone" }, "icu:DeleteMessagesModal--deleteFromAllDevices": { @@ -4801,7 +5021,7 @@ "description": "When creating a new group and inviting users, this is shown in the dialog" }, "icu:NewlyCreatedGroupInvitedContactsDialog--body--learn-more": { - "messageformat": "Meer leren hierover", + "messageformat": "Meer informatie", "description": "When creating a new group and inviting users, this is shown in the dialog" }, "icu:AddGroupMembersModal--title": { @@ -4817,7 +5037,7 @@ "description": "When adding new members to an existing group, this is shown in the confirmation dialog" }, "icu:AddGroupMembersModal--confirm-title--many": { - "messageformat": "{count,number} leden toevoegen aan “{group}”?", + "messageformat": "{count,number} leden toevoegen aan “{group}”?", "description": "When adding new members to an existing group, this is shown in the confirmation dialog" }, "icu:AddGroupMembersModal--confirm-button--one": { @@ -4829,7 +5049,7 @@ "description": "When adding new members to an existing group, this is shown on the confirmation dialog button" }, "icu:createNewGroupButton": { - "messageformat": "Nieuwe groep aanmaken", + "messageformat": "Nieuwe groep", "description": "The text of the button to create new groups" }, "icu:selectContact": { @@ -4861,7 +5081,7 @@ "description": "Aria label for audio attachment's Download button" }, "icu:MessageAudio--pending": { - "messageformat": "Audiobericht aan het downloaden 
", + "messageformat": "Audiobericht aan het downloaden
", "description": "Aria label for pending audio attachment spinner" }, "icu:MessageAudio--slider": { @@ -4905,7 +5125,7 @@ "description": "Toast message shown when trying to forward an empty or deleted message" }, "icu:MessageRequestWarning__learn-more": { - "messageformat": "Meer leren hierover", + "messageformat": "Meer informatie", "description": "Shown on the message request warning. Clicking this button will open a dialog with more information" }, "icu:MessageRequestWarning__dialog__details": { @@ -4961,7 +5181,7 @@ "description": "Header in the group contact spoofing review dialog. After this header, there will be a list of members" }, "icu:ContactSpoofingReviewDialog__group__name-change-info": { - "messageformat": "Heette kort geleden nog {oldName} maar heeft zijn of haar profielnaam naar {newName} gewijzigd.", + "messageformat": "Heeft recent zijn of haar profielnaam gewijzigd van “{oldName}” naar “{newName}”", "description": "In the group contact spoofing review dialog, this text is shown when someone has changed their name recently" }, "icu:RemoveGroupMemberConfirmation__remove-button": { @@ -4985,7 +5205,7 @@ "description": "First paragraph in the captcha dialog" }, "icu:CaptchaDialog__second-paragraph": { - "messageformat": "Je kunt doorgaan met het verzenden van berichten nadat je hebt geverifieerd dat je een mens bent. Enig bericht waarvan verzending is gepauzeerd zal dan automatisch verzonden worden.", + "messageformat": "Je kunt doorgaan met het verzenden van berichten nadat je hebt geverifieerd dat je een mens bent. Enig bericht waarvan verzenden is gepauzeerd zal dan automatisch verzonden worden.", "description": "First paragraph in the captcha dialog" }, "icu:CaptchaDialog--can-close__title": { @@ -5109,11 +5329,11 @@ "description": "aria-label for the custom color gradient creator knob" }, "icu:customDisappearingTimeOption": { - "messageformat": "Zelfgekozen tijdspanne", + "messageformat": "Zelfgekozen tijd", "description": "Text for an option in Disappearing Messages menu and Conversation Details Disappearing Messages setting when no user value is available" }, "icu:selectedCustomDisappearingTimeOption": { - "messageformat": "Zelfgekozen tijdspanne", + "messageformat": "Zelfgekozen tijd", "description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time" }, "icu:DisappearingTimeDialog__label--value": { @@ -5125,11 +5345,11 @@ "description": "aria-label for the units of time select box" }, "icu:DisappearingTimeDialog__title": { - "messageformat": "Zelfgekozen tijdspanne", + "messageformat": "Zelfgekozen tijd", "description": "Title for the custom disappearing message timeout dialog" }, "icu:DisappearingTimeDialog__body": { - "messageformat": "Kies zelf een tijdspanne voor verlopende berichten.", + "messageformat": "Kies zelf een timer voor verdwijnende berichten.", "description": "Body for the custom disappearing message timeout dialog" }, "icu:DisappearingTimeDialog__set": { @@ -5157,7 +5377,7 @@ "description": "Name of the 'weeks' unit select for the custom disappearing message timeout dialog" }, "icu:settings__DisappearingMessages__footer": { - "messageformat": "Stel een standaardtimer voor verlopende berichten in voor alle nieuwe chats die door jou zijn gestart.", + "messageformat": "Stel een standaardtimer voor verdwijnende berichten in voor alle nieuwe chats die jij zelf begint.", "description": "Footer for the Disappearing Messages settings section" }, "icu:settings__DisappearingMessages__timer__label": { @@ -5165,11 +5385,11 @@ "description": "Label for the Disappearing Messages default timer setting" }, "icu:UniversalTimerNotification__text": { - "messageformat": "Zodra je een bericht verzend zal de tijdspanne voor verlopende berichten op {timeValue} worden ingesteld.", + "messageformat": "Zodra je een bericht verzendt zal de timer voor verdwijnende berichten op {timeValue} worden ingesteld.", "description": "A message displayed when default disappearing message timeout is about to be applied" }, "icu:ContactRemovedNotification__text": { - "messageformat": "Je hebt deze persoon verwijderd. Als je hen opnieuw een bericht stuurt, wordt diegene weer aan je lijst toegevoegd.", + "messageformat": "Je hebt deze persoon verwijderd. Als je hem of haar opnieuw een bericht stuurt, wordt diegene weer aan je lijst toegevoegd.", "description": "A message displayed when contact was removed and will be added back on an outgoing message" }, "icu:ErrorBoundaryNotification__text": { @@ -5185,7 +5405,7 @@ "description": "Label text shown when editing group description" }, "icu:ConversationDetailsHeader--add-group-description": { - "messageformat": "Voeg een groepsomschrijving toe 
", + "messageformat": "Voeg een groepsomschrijving toe
", "description": "Placeholder text in the details header for those that can edit the group description" }, "icu:MediaQualitySelector--button": { @@ -5201,7 +5421,7 @@ "description": "Title for option for standard quality" }, "icu:MediaQualitySelector--standard-quality-description": { - "messageformat": "Sneller, minder gegevensoverdracht", + "messageformat": "Sneller, minder dataverbruik", "description": "Description of standard quality selector" }, "icu:MediaQualitySelector--high-quality-title": { @@ -5209,7 +5429,7 @@ "description": "Title for option for high quality" }, "icu:MediaQualitySelector--high-quality-description": { - "messageformat": "Langzamer, meer gegevensoverdracht", + "messageformat": "Langzamer, meer dataverbruik", "description": "Description of high quality selector" }, "icu:MessageDetailsHeader--Failed": { @@ -5241,7 +5461,7 @@ "description": "In the message details screen, shown as a label of how long it will be before the message disappears" }, "icu:MessageDetail__view-edits": { - "messageformat": "Bekijk bewerkingsgeschiedenis", + "messageformat": "Bewerkingsgeschiedenis bekijken", "description": "Link to view a message's edit history" }, "icu:ProfileEditor--about": { @@ -5252,10 +5472,30 @@ "messageformat": "Gebruikersnaam", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Er is iets misgegaan met je gebruikersnaam, deze is niet meer aan je account toegewezen.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Gebruikersnaam verwijderen", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Gebruikersnaam aanmaken", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-code of link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Gebruikersnaam moet worden vernieuwd", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Gebruikersnaamlink moet worden vernieuwd", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Deel je gebruikersnaam", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Gebruikersnaam verwijderen", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Je staat op het punt je gebruikersnaam te verwijderen. Als je doorgaat kunnen anderen deze naam claimen. Weet je het zeker?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Dit verwijdert je gebruikersnaam en schakelt je QR-code en link uit. Anderen kunnen \"{username}\" claimen. Weet je het zeker?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5481,11 +5717,11 @@ "description": "Label for changing the zoom level" }, "icu:Preferences__link-previews--title": { - "messageformat": "Voorbeeld van website meesturen", + "messageformat": "Linkvoorbeelden meesturen", "description": "Title for the generate link previews setting" }, "icu:Preferences__link-previews--description": { - "messageformat": "Open de Signal-app op je mobiele telefoon en ga naar Instellingen > Chats om deze instellingen te veranderen", + "messageformat": "Open de Signal-app op je mobiele telefoon en ga naar Instellingen > Chats om deze instelling te veranderen", "description": "Description for the generate link previews setting" }, "icu:Preferences--advanced": { @@ -5597,11 +5833,11 @@ "description": "Label for Device list in call settings pane" }, "icu:Preferences__turn-stories-on": { - "messageformat": "Zet verhalen aan", + "messageformat": "Verhalen aanzetten", "description": "Label to enable stories" }, "icu:Preferences__turn-stories-off": { - "messageformat": "Zet verhalen uit", + "messageformat": "Verhalen uitzetten", "description": "Label to disable stories" }, "icu:Preferences__turn-stories-off--action": { @@ -5609,15 +5845,51 @@ "description": "Label in confirmation modal to disable stories" }, "icu:Preferences__turn-stories-off--body": { - "messageformat": "Je kunt geen verhalen meer delen of bekijken. Updates die je recent in je verhaal gedeeld hebt, worden ook gewist.", + "messageformat": "Je kunt geen verhalen meer delen of bekijken. Updates die je recent op je verhaal hebt gedeeld, worden ook gewist.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Taal", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Taal", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Systeemtaal", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Zoek talen", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Geen resultaten voor “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Instellen", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Start Signal opnieuw op om toe te passen", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Om de taal te wijzigen, moet de app opnieuw opgestart worden.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Opnieuw opstarten", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Nieuwe versie {version} is beschikbaar", "description": "Tooltip for new update available" }, "icu:DialogUpdate__downloading": { - "messageformat": "Update downloaden...", + "messageformat": "Update downloaden
", "description": "The title of update dialog when update download is in progress." }, "icu:DialogUpdate__downloaded": { @@ -5696,6 +5968,10 @@ "messageformat": "Er is een fout opgetreden bij het opslaan van je instellingen. Probeer het opnieuw.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Bericht", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Meer stijlen", "description": "Action button for switching up the clock styles" @@ -5861,7 +6137,7 @@ "description": "Payment event activation from you label" }, "icu:payment-event-notification-label": { - "messageformat": "Overschrijving", + "messageformat": "Betaling", "description": "Payment event notification label" }, "icu:payment-event-notification-check-primary-device": { @@ -5989,7 +6265,7 @@ "description": "Story settings modal group story selection subtitle" }, "icu:StoriesSettings__viewers": { - "messageformat": "{count, plural, one {Door {count,number} persoon gezien} other {Door {count,number} personen gezien}}", + "messageformat": "{count, plural, one {{count,number} kijker} other {{count,number} kijkers}}", "description": "The number of viewers for a story distribution list" }, "icu:StoriesSettings__who-can-see": { @@ -6033,7 +6309,7 @@ "description": "Confirmation text to delete a custom distribution list" }, "icu:StoriesSettings__choose-viewers": { - "messageformat": "Gebruikers kiezen", + "messageformat": "Ontvangers kiezen", "description": "Modal title when choosing to add a viewer to a custom distribution list" }, "icu:StoriesSettings__name-story": { @@ -6089,7 +6365,7 @@ "description": "Label of view receipts checkbox in story settings" }, "icu:StoriesSettings__view-receipts--description": { - "messageformat": "Open de Signal-app op je mobiele telefoon en navigeer naar Instellingen > Verhalen om deze instellingen te veranderen", + "messageformat": "Open de Signal-app op je mobiele telefoon en navigeer naar Instellingen > Verhalen om deze instelling te veranderen", "description": "Description of how view receipts can be changed in story settings" }, "icu:GroupStorySettingsModal__members_title": { @@ -6101,7 +6377,7 @@ "description": "Stories settings > Group Story > group story help text" }, "icu:GroupStorySettingsModal__remove_group": { - "messageformat": "Verwijder groepsverhaal", + "messageformat": "Groepsverhaal verwijderen", "description": "Stories settings > Group Story > button to remove group story" }, "icu:StoriesSettings__remove_group--confirm": { @@ -6113,7 +6389,7 @@ "description": "Shown during the first time posting a story" }, "icu:SendStoryModal__title": { - "messageformat": "Verzonden aan", + "messageformat": "Versturen naar", "description": "Title for the send story modal" }, "icu:SendStoryModal__send": { @@ -6209,7 +6485,7 @@ "description": "Select box description for the stories on/off toggle" }, "icu:Stories__settings-toggle--button": { - "messageformat": "Zet verhalen uit", + "messageformat": "Verhalen uitzetten", "description": "Button to turn off stories in stories settings modal" }, "icu:StoryViewer__pause": { @@ -6289,7 +6565,7 @@ "description": "Placeholder text for when there are no views" }, "icu:StoryViewsNRepliesModal__tab--views": { - "messageformat": "Aantal weergaven", + "messageformat": "Gezien door", "description": "Title for views tab" }, "icu:StoryViewsNRepliesModal__tab--replies": { @@ -6341,7 +6617,7 @@ "description": "Label for menu item to get a story's information" }, "icu:StoryListItem__hide-modal--body": { - "messageformat": "Als je dit verhaal verbergt dan zullen nieuwe verhalen van {name} niet langer bovenaan de lijst met verhalen worden weergegeven.", + "messageformat": "Als je dit verhaal verbergt dan zullen nieuwe verhaaldelen van {name} niet langer bovenaan de lijst met verhalen worden weergegeven.", "description": "Body for the confirmation dialog for hiding a story" }, "icu:StoryListItem__hide-modal--confirm": { @@ -6429,7 +6705,7 @@ "description": "aria-label for adding a link preview" }, "icu:StoryCreator__link-preview-placeholder": { - "messageformat": "Typ of plak een verwijzing", + "messageformat": "Typ of plak een URL", "description": "Placeholder for the URL input for link previews" }, "icu:StoryCreator__link-preview-empty": { @@ -6529,7 +6805,11 @@ "description": "Text of disclaimer at the bottom of the username link modal" }, "icu:UsernameLinkModalBody__reset": { - "messageformat": "Standaardinstelling herstellen", + "messageformat": "QR-code vernieuwen", + "description": "Text of button at the bottom of the username link modal" + }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Klaar", "description": "Text of button at the bottom of the username link modal" }, "icu:UsernameLinkModalBody__color__radio": { @@ -6537,9 +6817,17 @@ "description": "ARIA label of button for selecting username link color" }, "icu:UsernameLinkModalBody__reset__confirm": { - "messageformat": "Als je je QR-code reset, werken je bestaande QR-code en link niet meer.", + "messageformat": "Als je je QR-code vernieuwd, werken je bestaande QR-code en link niet meer.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Link aan het vernieuwen
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-code en link niet ingesteld. Check je netwerkverbinding en probeer het opnieuw.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Je Signal-gebruikersnaam instellen", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "bewerkt", + "messageformat": "Bewerkt", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,8 +6880,116 @@ "messageformat": "Opnieuw verzenden", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Meer acties", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Oproepen", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nieuwe oproep", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nieuwe oproep", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Meer acties", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Oproepgeschiedenis wissen", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Oproepgeschiedenis wissen?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Hiermee wordt de oproepgeschiedenis voorgoed verwijderd", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Verwijderen", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Oproepgeschiedenis gewist", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klik om te bekijken of een oproep te starten", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Zoeken", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filteren op gemist", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Schuifschakelaar", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Geen recente oproepen. Ga aan de slag door een contact te bellen.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Geen resultaten voor “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Inkomend", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Uitgaand", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Gemist", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Groepsoproep", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Geen recente gesprekken.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Geen resultaten voor “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Uitgaande spraakoproep} other {Inkomende spraakoproep}}} Video {{direction, select, Outgoing {Uitgaande video-oproep} other {Inkomende video-oproep}}} Group {{direction, select, Outgoing {Uitgaande groepsoproep} other {Inkomende groepsoproep}}} other {{direction, select, Outgoing {Uitgaande oproep} other {Inkomende oproep}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Gemiste spraakoproep} Video {Gemiste video-oproep} Group {Gemiste groepsoproep} other {Gemiste oproep}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Onbeantwoorde spraakoproep} Video {Onbeantwoorde video-oproep} Group {Onbeantwoorde groepsoproep} other {Onbeantwoorde oproep}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Spraakoproep geweigerd} Video {Video-oproep geweigerd} Group {Groepsoproep geweigerd} other {Oproep geweigerd}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ander is aan het typen.} other {{count,number} anderen zijn aan het typen.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { - "messageformat": "wat er nieuw is", + "messageformat": "Wat er nieuw is", "description": "Title for the whats new modal" }, "icu:WhatsNew__bugfixes": { @@ -6624,10 +7020,22 @@ "messageformat": "Kleine aanpassingen, bugfixes en prestatieverbeteringen. Bedankt dat je Signal gebruikt!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Deze update bevat enkele verbeteringen voor spraak- en video-oproepen en enkele, kleine wijzigingen van de documentatie (bedankt, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Je kunt nu je geselecteerde taal in Signal wijzigen zonder je systeeminstellingen te wijzigen (Signal-instellingen > Uiterlijk > Taal)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "We hebben de notificatiepictogrammen voor groepsupdates aangepast, bijvoorbeeld als iemand wordt toegevoegd aan een groep. Deze pictogrammen verbeteren de leesbaarheid (met name in de donkere modus). De oude pictogrammen konden het donker nauwelijks aan. Deze nieuwe pictogrammen zijn ervoor gemaakt." + "icu:WhatsNew__v6.39--1": { + "messageformat": "We hebben een korte vertraging opgelost die soms optrad tijdens het wachten in het wachtscherm op macOS-apparaten. Nu is er in ieder geval één excuus minder om een halve seconde te laat te zijn voor de vergadering." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "We hebben de overgangsanimaties gerepareerd voor videotegels die verschijnen wanneer iemand deelneemt aan een groepsoproep of deze verlaat. Wanneer je het gezicht van een contact in beeld ziet komen, dan is dat een sociale beweging." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Je kunt nu op een profielfoto of groepsafbeelding in de chatkop klikken om snel toegang te krijgen tot de chatinstellingen of om nog niet bekeken verhalen uit die chat te bekijken. Bedankt {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/pa-IN/messages.json b/_locales/pa-IN/messages.json index 107691388d..e2c239a05e 100644 --- a/_locales/pa-IN/messages.json +++ b/_locales/pa-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àšĄà©‡àšŸàšŸàšŹà©‡àšž àš€àš°à©à©±àšŸà©€", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àšĄàšŸàšŸàšŸàšŹà©‡àšž àš”àšżà©±àšš àš•à©‹àšˆ àš—à©œàšŹà©œ àš†àšˆà„€ àš€à©àšžà©€àš‚ àš—à©œàšŹà©œ àšŹàšŸàš°à©‡ àšœàšŸàšŁàš•àšŸàš°à©€ àš•àšŸàšȘੀ àš•àš° àšžàš•àšŠà©‡ àščੋ àš…àš€à©‡ àšžàšźà©±àšžàšżàš† àššà©‚à©° àščੱàšČ àš•àš°àšš àšČàšˆ Signal àšžàščàšŸàš‡àš€àšŸ àšŸà©€àšź àššàšŸàšČ àšžà©°àšȘàš°àš• àš•àš° àšžàš•àšŠà©‡ àščà©‹à„€ àšœà©‡àš•àš° àš€à©àšžà©€àš‚ àš€à©àš°à©°àš€ Signal àšŠà©€ àš”àš°àš€à©‹àš‚ àš•àš°àššàšŸ àššàšŸàščà©à©°àšŠà©‡ àščੋ, àš€àšŸàš‚ àš€à©àšžà©€àš‚ àš†àšȘàšŁàšŸ àšĄàšŸàšŸàšŸ àšźàšżàšŸàšŸ àšžàš•àšŠà©‡ àščੋ àš…àš€à©‡ àšźà©à©œ-àššàšŸàšČੂ àš•àš° àšžàš•àšŠà©‡ àščà©‹à„€\n\nàš‡à©±àš„à©‡à©‡ àšœàšŸ àš•à©‡ àšžàščàšŸàš‡àš€àšŸ àšŸà©€àšź àššàšŸàšČ àšžà©°àšȘàš°àš• àš•àš°à©‹: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àšžàšŸàš°àšŸ àšĄà©‡àšŸàšŸ àšźàšżàšŸàšŸàš“ àš…àš€à©‡ àšźà©à©œ-àššàšŸàšČੂ àš•àš°à©‹", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àšĄàšŸàšŸàšŸ àšźàšżàšŸàšŸàš“ àš…àš€à©‡ àšźà©à©œ-àššàšŸàšČੂ àš•àš°à©‹", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àš•à©€ àšžàšŸàš°àšŸ àšĄàšŸàšŸàšŸ àšžàš„àšŸàšˆ àš€à©Œàš° 'àš€à©‡ àšźàšżàšŸàšŸàš‰àšŁàšŸ àščੈ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àš€à©àščàšŸàšĄà©‡ àšĄàšżàš”àšŸàšˆàšž àš”àšżà©±àššà©‹àš‚ àšžàšŸàš°à©‡ àšȘà©àš°àšŸàšŁà©‡ àšžà©àššà©‡àščੇ àš…àš€à©‡ àšźà©€àšĄà©€àš† àšžàš„àšŸàšˆ àš€à©Œàš° 'àš€à©‡ àšźàšżàšŸàšŸ àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸà„€ àš€à©àšžà©€àš‚ àš‡àšž àšĄàšżàš”àšŸàšˆàšž àššà©‚à©° àšŠà©àšŹàšŸàš°àšŸ àšČàšżà©°àš• àš•àš°àšš àš€à©‹àš‚ àšŹàšŸàš…àšŠ àš‡àšž àš‰à©±àš€à©‡ Signal àšŠà©€ àš”àš°àš€à©‹àš‚ àš•àš° àšžàš•à©‹àš—à©‡à„€ àš‡àšž àššàšŸàšČ àš€à©àščàšŸàšĄà©‡ à©žà©‹àšš àš”àšżà©±àššà©‹àš‚ àš•à©‹àšˆ àš”à©€ àšĄàšŸàšŸàšŸ àšźàšżàšŸàšŸàšàš—àšŸ àššàščà©€àš‚ àšœàšŸàš”à©‡àš—àšŸà„€", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àš€à©àščàšŸàšĄà©‡ àšĄàšŸàšŸàšŸàšŹà©‡àšž àšŠàšŸ àš”àš°à©›àšš Signal àšŠà©‡ àš‡àšž àš”àš°à©›àšš àššàšŸàšČ àšźà©‡àšČ àššàščà©€àš‚ àš–àšŸ àš°àšżàščàšŸ àščà©ˆà„€ àšŻàš•à©€àššà©€ àšŹàšŁàšŸàš“ àš•àšż àš€à©àšžà©€àš‚ àš†àšȘàšŁà©‡ àš•à©°àšȘàšżàšŠàšŸàš° 'àš€à©‡ Signal àšŠàšŸ àšžàš­ àš€à©‹àš‚ àššàš”àšŸàš‚ àš”àš°à©›àšš àš–à©‹àšČ੍àšč àš°àščੇ àščà©‹à„€", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "àš«àšŸàš‡àšČ(&F)", @@ -300,6 +316,70 @@ "messageformat": "àššà©ˆàšŸàšŸàš‚", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àš€à©àščàšŸàšĄà©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšŠà©‡ àššàšŸàšČ àš•à©àš àš—àšČàš€ àš”àšŸàšȘàš° àš—àšżàš† àščੈ, àš‡àšč àščà©àšŁ àš€à©àščàšŸàšĄà©‡ àš–àšŸàš€à©‡ àššà©‚à©° àš…àšžàšŸàšˆàšš àššàščà©€àš‚ àš•à©€àš€àšŸ àš—àšżàš† àščà©ˆà„€ àš€à©àšžà©€àš‚ àš‡àšžàššà©‚à©° àšŠà©àšŹàšŸàš°àšŸ àšžà©ˆà©±àšŸ àš•àš°àšš àšŠà©€ àš•à©‹àšžàšŒàšżàšžàšŒ àš•àš° àšžàš•àšŠà©‡ àščੋ àšœàšŸàš‚ àš‡à©±àš• àššàš”àšŸàš‚ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àššà©àšŁ àšžàš•àšŠà©‡ àščà©‹à„€", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àščà©àšŁà©‡ àš à©€àš• àš•àš°à©‹", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àš€à©àščàšŸàšĄà©‡ QR àš•à©‹àšĄ àš…àš€à©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšŠà©‡ àššàšŸàšČ àš•à©àš àš—àšČàš€ àš”àšŸàšȘàš° àš—àšżàš† àščੈ, àš‡àšč àščà©àšŁ àš”à©ˆàš§ àššàščà©€àš‚ àščà©ˆà„€ àšŠà©‚àšœàšżàš†àš‚ àššàšŸàšČ àšžàšŸàš‚àšàšŸ àš•àš°àšš àšČàšˆ àš‡à©±àš• àššàš”àšŸàš‚ àšČàšżà©°àš• àšŹàšŁàšŸàš“à„€", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àščà©àšŁà©‡ àš à©€àš• àš•àš°à©‹", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àšŸà©ˆàšŹàšŸàš‚ àšŠàšżàš–àšŸàš“", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àšŸà©ˆàšŹàšŸàš‚ àššà©‚à©° àšČà©àš•àšŸàš“", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àš•à©‹àšˆ àš—à©œàšŹà©œ àščੋ àš—àšˆ àščੈ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} àššàščà©€àš‚ àšȘੜ੍àščੇ", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àššàščà©€àš‚-àšȘੜ੍àščàšżàš† àš—àšżàš† àš”àšœà©‹àš‚ àššàšżà©°àššà©àščàšżàš€ àš•à©€àš€àšŸ àš—àšżàš†", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àššà©ˆàšŸàšŸàš‚", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àš•àšŸàšČàšŸàš‚", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àšžàšŸà©‹àš°à©€àš†àš‚", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àšžà©ˆàšŸàšżà©°àš—àšŸàš‚", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal àššà©‚à©° àš…à©±àšȘàšĄà©‡àšŸ àš•àš°à©‹", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àšȘà©àš°à©‹àš«àšŸàšˆàšČ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àš”àšŸàšȘàšž", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àš‡àščàššàšŸàš‚ àššà©ˆàšŸàšŸàš‚ àššà©‚à©° àš†àš°àš•àšŸàšˆàš” àš•à©€àš€à©€àš†àš‚ àš—àšˆàš†àš‚ àščàšš àš…àš€à©‡ àšžàšżàš°à©ž àš‰àšŠà©‹àš‚ àščੀ àšŠàšżàš–àšŸàšˆ àšŠà©‡àšŁàš—à©€àš†àš‚ àšœàšŠà©‹àš‚ àš‡àššàšŹàšŸàš•àšž àš”àšżà©±àšš àššàš”à©‡àš‚ àšžà©àššà©‡àščੇ àš†àš‰àšŁàš—à©‡à„€", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àš«àšżàš° àš”à©€ àš•àšŸàšČ àš•àš°à©‹", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àš«àšżàš° àš”à©€ àš¶àšŸàšźàšČ àščà©‹àš”à©‹", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àš•àšŸàšČ àšœàšŸàš°à©€ àš°à©±àš–à©‹", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°àšŸàš‚ àššà©‚à©° àš…à©±àšȘàšĄà©‡àšŸ àš•à©€àš€àšŸ àšœàšŸ àš°àšżàščàšŸ àščà©ˆà„€", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àščà©‹àš° àšœàšŸàšŁà©‹", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àšȘàšżàš›àšČàšŸ àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àš…àš—àšČàšŸ àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš° àšŠàšŸ àš”àš°à©›àšš, {total,number} àš”àšżà©±àššà©‹àš‚ {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àš€àšžàšŠà©€àš•àš¶à©àšŠàšŸ àš”àšœà©‹àš‚ àššàšżà©°àššà©àšč àšČàš—àšŸàš“", @@ -663,33 +747,41 @@ "messageformat": "àš€àšžàšŠà©€àš• àššà©‚à©° àščàšŸàšŸàš“", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} àšŠà©‡ àššàšŸàšČ àšžàšżàš°à©‡-àš€à©‹àš‚-àšžàšżàš°à©‡ àš€à©±àš• àš‡àššàš•à©àš°àšżàšȘàš¶àšš àšŠà©€ àš€àšžàšŠà©€àš• àš•àš°àšš àšČàšˆ, àš‰à©±àšȘàš° àšŠàšżà©±àš€à©‡ àššà©°àšŹàš°àšŸàš‚ àššà©‚à©° àš‰àščàššàšŸàš‚ àšŠà©‡ àšĄàšżàš”àšŸàšˆàšž àš”àšżà©±àšš àšŠàšżàš–àšŸàš àššà©°àšŹàš°àšŸàš‚ àšŠà©‡ àššàšŸàšČ àšźàšżàšČàšŸàš“à„€ àš‰àšč àš†àšȘàšŁà©‡ àšĄàšżàš”àšŸàšˆàšž àššàšŸàšČ àš€à©àščàšŸàšĄà©‡ àš•à©‹àšĄ àššà©‚à©° àš”à©€ àšžàš•à©ˆàšš àš•àš° àšžàš•àšŠà©‡ àščàššà„€", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àščà©‹àš° àšœàšŸàšŁà©‹", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} àšŠà©‡ àššàšŸàšČ àšžàšżàš°à©‡-àš€à©‹àš‚-àšžàšżàš°à©‡ àš€à©±àš• àš‡àššàš•à©àš°àšżàšȘàš¶àšš àšŠà©€ àš€àšžàšŠà©€àš• àš•àš°àšš àšČàšˆ, àš‰à©±àšȘàš° àšŠàšżà©±àš€à©‡ àš°à©°àš—à©€àšš àš•àšŸàš°àšĄ àššà©‚à©° àš‰àščàššàšŸàš‚ àšŠà©‡ àšĄàšżàš”àšŸàšˆàšž àššàšŸàšČ àšźàšżàšČàšŸàš“ àš…àš€à©‡ àššà©°àšŹàš°àšŸàš‚ àšŠà©€ àš€à©àšČàššàšŸ àš•àš°à©‹à„€ àšœà©‡àš•àš° àš‡àšč àšźà©‡àšČ àššàščà©€àš‚ àš–àšŸàš‚àšŠà©‡, àš€àšŸàš‚ àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°àšŸàš‚ àšŠà©€ àšŠà©‚àšœà©€ àšœà©‹à©œà©€ àššà©‚à©° àšźàšżàšČàšŸ àš•à©‡ àšŠà©‡àš–à©‹à„€ àšžàšżàš°àš«àšŒ àš‡à©±àš• àšœà©‹à©œà©€ àšŠà©‡ àšźà©‡àšČ àš–àšŸàšŁ àšŠà©€ àšČੋੜ àščà©ˆà„€", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} àšŠà©‡ àššàšŸàšČ àšžàšżàš°à©‡-àš€à©‹àš‚-àšžàšżàš°à©‡ àš€à©±àš• àš‡àššàš•à©àš°àšżàšȘàš¶àšš àšŠà©€ àš€àšžàšŠà©€àš• àš•àš°àšš àšČàšˆ, àš‰à©±àšȘàš° àšŠàšżà©±àš€à©‡ àššà©°àšŹàš°àšŸàš‚ àššà©‚à©° àš‰àščàššàšŸàš‚ àšŠà©‡ àšĄàšżàš”àšŸàšˆàšž àš”àšżà©±àšš àšŠàšżàš–àšŸàš àššà©°àšŹàš°àšŸàš‚ àšŠà©‡ àššàšŸàšČ àšźàšżàšČàšŸàš“à„€ àš‰àšč àš†àšȘàšŁà©‡ àšĄàšżàš”àšŸàšˆàšž àššàšŸàšČ àš€à©àščàšŸàšĄà©‡ àš•à©‹àšĄ àššà©‚à©° àš”à©€ àšžàš•à©ˆàšš àš•àš° àšžàš•àšŠà©‡ àščàššà„€", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°àšŸàš‚ àš”àšżà©±àšš àšŹàšŠàšČàšŸàš…", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal àš”àšżà©±àšš àš†àš‰àšŁ àš”àšŸàšČੇ àšȘàš°àšŠà©‡àšŠàšŸàš°à©€ àš«à©€àššàš°àšŸàš‚ àššà©‚à©° àšžàšźàš°à©±àš„ àšŹàšŁàšŸàš‰àšŁ àšČàšˆ àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°àšŸàš‚ àššà©‚à©° àš…à©±àšȘàšĄà©‡àšŸ àš•à©€àš€àšŸ àšœàšŸ àš°àšżàščàšŸ àščà©ˆà„€\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°àšŸàš‚ àšŠà©€ àš€àšžàšŠà©€àš• àš•àš°àšš àšČàšˆ, àš°à©°àš—à©€àšš àš•àšŸàš°àšĄ àššà©‚à©° àš†àšȘàšŁà©‡ àšžà©°àšȘàš°àš• àšŠà©‡ àšĄàšżàš”àšŸàšˆàšž àššàšŸàšČ àšźàšżàšČàšŸàš“à„€ àšœà©‡àš•àš° àš‡àšč àšźà©‡àšČ àššàščà©€àš‚ àš–àšŸàš‚àšŠà©‡, àš€àšŸàš‚ àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš°àšŸàš‚ àšŠà©€ àšŠà©‚àšœà©€ àšœà©‹à©œà©€ àššà©‚à©° àšźàšżàšČàšŸ àš•à©‡ àšŠà©‡àš–à©‹à„€ àšžàšżàš°àš«àšŒ àš‡à©±àš• àšœà©‹à©œà©€ àšŠà©‡ àšźà©‡àšČ àš–àšŸàšŁ àšŠà©€ àšČੋੜ àščà©ˆà„€", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àšźàšŠàšŠ àššàšŸàščà©€àšŠà©€ àščੈ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àšžàšźàš àš—àš", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àšœàšŠà©‹àš‚ àš€à©àšžà©€àš‚ àš‡àšž àš”àšżàš…àš•àš€à©€ àššà©‚à©° àšžà©àššà©‡àščੇ àš­à©‡àšœà©‹àš—à©‡ àšœàšŸàš‚ àšȘà©àš°àšŸàšȘàš€ àš•àš°à©‹àš—à©‡ àš€àšŸàš‚ àš‡àščàššàšŸàš‚ àššàšŸàšČ àš‡à©±àš• àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš° àšŹàšŁàšŸàš‡àš† àšœàšŸàš”à©‡àš—àšŸà„€", @@ -1267,10 +1359,6 @@ "messageformat": "àščàšŸàšČà©€àš† àšźà©€àšĄà©€àš† àššà©‚à©° àš”à©‡àš–à©‹", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} àšŠà©‡ àššàšŸàšČ àš†àšȘàšŁà©€ àšžàšżàš°à©‡-àš€à©‹àš‚-àšžàšżàš°à©‡ àš€à©±àš• àš‡àššàš•à©àš°àšżàšȘàš¶àšš àšŠà©€ àš€àšžàšŠà©€àš• àš•àš°àšš àšČàšˆ, àš‰à©±àšȘàš° àšŠàšżà©±àš€à©‡ àššà©°àšŹàš°àšŸàš‚ àššà©‚à©° àš‰àščàššàšŸàš‚ àšŠà©‡ àšĄàšżàš”àšŸàšˆàšž àš”àšżà©±àšš àšŠàšżàš–àšŸàš àššà©°àšŹàš°àšŸàš‚ àšŠà©‡ àššàšŸàšČ àšźàšżàšČàšŸàš“à„€ àš‰àšč àš‰à©±àšȘàš° àšŠàšżà©±àš€à©‡ QR àš•à©‹àšĄ àššà©‚à©° àš”à©€ àšžàš•à©ˆàšš àš•àš° àšžàš•àšŠà©‡ àščàššà„€", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àš€à©àšžà©€àš‚ àš…àšœà©‡ àš€àš• àš‡àšž àšžà©°àšȘàš°àš• àšŠà©‡ àššàšŸàšČ àš•àšżàšžà©‡ àš”à©€ àšžà©àššà©‡àščੇ àšŠàšŸ àš†àšŠàšŸàšš-àšȘà©àš°àšŠàšŸàšš àššàščà©€àš‚ àš•à©€àš€àšŸ àščà©ˆà„€ àš‰àščàššàšŸàš‚ àšŠà©‡ àššàšŸàšČ àš€à©àščàšŸàšĄàšŸ àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš° àšȘàščàšżàšČੇ àšžà©àššà©‡àščੇ àš€à©‹àš‚ àšŹàšŸàš…àšŠ àš‰àšȘàšČàšŹàš§ àščà©‹àš”à©‡àš—àšŸà„€" }, @@ -1334,17 +1422,17 @@ "messageformat": "àšœàšŸàšŁàš•àšŸàš°à©€", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àšźàšżàšŸàšŸàš“", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àšžà©àššà©‡àščੇ àšźàšżàšŸàšŸàš“", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àš•à©€ àššà©ˆàšŸ àššà©‚à©° àšźàšżàšŸàšŸàš‰àšŁàšŸ àščੈ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àš•à©€ àšžà©àššà©‡àščàšżàš†àš‚ àššà©‚à©° àšźàšżàšŸàšŸàš‰àšŁàšŸ àščੈ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àš‡àšž àššà©ˆàšŸ àššà©‚à©° àš‡àšž àšĄàšżàš”àšŸàšˆàšž àš”àšżà©±àššà©‹àš‚ àšźàšżàšŸàšŸ àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸà„€", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àš‡àšž àššà©ˆàšŸ àš”àšżàššàšČੇ àšžà©àššà©‡àščàšżàš†àš‚ àššà©‚à©° àš‡àšž àšĄàšżàš”àšŸàšˆàšž àš”àšżà©±àššà©‹àš‚ àšźàšżàšŸàšŸ àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸà„€ àšžà©àššà©‡àščੇ àšźàšżàšŸàšŸàš‰àšŁ àš€à©‹àš‚ àšŹàšŸàš…àšŠ àš”à©€ àš€à©àšžà©€àš‚ àš‡àšž àššà©ˆàšŸ àšŠà©€ àš–à©‹àšœ àš•àš° àšžàš•àšŠà©‡ àščà©‹à„€", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àš—àš°à©à©±àšȘ àš›à©±àšĄà©‹", @@ -1438,6 +1526,14 @@ "messageformat": "àš€à©àščàšŸàšĄà©€àš†àš‚ àšŠà©‹àš”àšŸàš‚ àššà©ˆàšŸàšŸàš‚ àšŠà©‡ àšȘà©àš°àšŸàšŁà©‡ àšžà©àššà©‡àščàšżàš†àš‚ àššà©‚à©° àš‡à©±àš„à©‡ àš‡àš•à©±àš àšŸ àš•àš° àšŠàšżà©±àš€àšŸ àš—àšżàš† àščà©ˆà„€", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} àššà©°àšŹàš° {conversationTitle} àšŠàšŸ àščà©ˆà„€ àš€à©àšžà©€àš‚ àšŠà©‹àš”à©‡àš‚ {sharedGroup} àšŠà©‡ àšźà©ˆàš‚àšŹàš° àščà©‹à„€", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} àššà©°àšŹàš° {conversationTitle} àšŠàšŸ àščੈ", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àščàš”àšŸàšČàšŸ àšŠàšżà©±àš€à©‡ àšžà©àššà©‡à©‡àščੇ àš€à©‹àš‚ àššàšżà©±àš€àš° àšŠàšŸ àš„à©°àšŹàššà©‡àšČ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àšŠà©àšŹàšŸàš°àšŸ àš•àšŸàšČ àš•àš°à©‹", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àš•àšŸàšČ àšžàšŒà©àš°à©‚ àš•àš°à©‹", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àš•àšŸàšČ 'àšš àščàšżà©±àšžàšŸ àšČàš”à©‹", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àš•àšŸàšČ àš”àšżà©±àšš àšŹàščà©àš€ à©›àšżàš†àšŠàšŸ àšČà©‹àš• àščà©‹àšŁ àš•àšŸàš°àšš àšźàšŸàšˆàš•à©àš°à©‹àš«àšŒà©‹àšš àšźàšżàšŠàšŸ àš•à©€àš€àšŸ àš—àšżàš†", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àš•àšŸàšČ àšžà©‚àššàššàšŸàš”àšŸàš‚", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àš•àšŸàšČ àš­àš°à©€ àščà©‹àšˆ àščੈ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àš•à©ˆàšźàš°àšŸ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àš¶àšŸàšźàšČ àščà©‹àš”à©‹", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àš¶à©àš°à©‚ àš•àš°à©‹", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àš•àšŸàšČ àš­àš°à©€ àščà©‹àšˆ àščੈ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àš•à©ˆàšźàš°àšŸ àš…àšžàšźàš°à©±àš„ àščੈ", @@ -1621,10 +1725,6 @@ "messageformat": "àš•à©ˆàšźàš°àšŸ àššàšŸàšČੂ àš•àš°à©‹", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àšźàšżàšŠàšŸ àš•àš°à©‹", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àšźàšŸàšˆàš•àš°à©‹àš«àšŒà©‹àšš àš…àšžàšźàš°à©±àš„", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àšźàšŸàšˆàš• àššà©‚à©° àš…àššàšźàšżàšŠàšŸ àš•àš°à©‹", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àšžàšŸàš‚àšàšŸ àš•àš°à©‹", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àšȘà©‡àšžàšŒ àš•àš°àššàšŸ àš…àšžàšźàš°à©±àš„ àščੈ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àšȘà©‡àšžàšŒ àš•àš°àššàšŸ àš°à©‹àš•à©‹", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àš°àšżà©°àš—", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àš­àšŸàš—à©€àšŠàšŸàš°àšŸàš‚ àššà©‚à©° àš•àšŸàšČ àš•àš°àšš àšČàšˆ àš—àš°à©à©±àšȘ àšŹàščà©àš€ àš”à©±àšĄàšŸ àščà©ˆà„€", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àš°àšżà©°àš— àš•àš°àššà©€ àšžàšźàš°à©±àš„ àš•àš°à©‹", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àš°àšżà©°àš— àšŹà©°àšŠ àš•àš°à©‹", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àš°àšżà©°àš— àššàšŸàšČੂ àš•àš°à©‹", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àščà©‹àš° àš”àšżàš•àšČàšȘ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àš€à©àšžà©€àš‚", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àš€à©àščàšŸàšĄàšŸ àš•à©ˆàšźàš°àšŸ àšŹà©°àšŠ àščੈ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš° àšŠà©‡àš–à©‹", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àšžà©àššà©‡àščàšŸ àš­à©‡àšœà©‹", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àšžà©àš°à©±àš–àšżàš† àššà©°àšŹàš° àšŠà©‡àš–à©‹", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "à©žà©‹àšš àššà©°àšŹàš° àščàšŸàšžàšČ àš•àš°àšš àš”àšżà©±àšš àš…àšžàš«àšČ àš°àščà©‡à„€ àš†àšȘàšŁà©‡ àš•àššà©ˆàš•àšžàšŒàšš àšŠà©€ àšœàšŸàš‚àšš àš•àš°à©‹ àš…àš€à©‡ àšŠà©àšŹàšŸàš°àšŸ àš•à©‹àšžàšŒàšżàšžàšŒ àš•àš°à©‹à„€", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àš‡àšž àšžà©àššà©‡àščੇ àššà©‚à©° àš­à©‡àšœà©‡ àšœàšŸàšŁ àš€à©‹àš‚ 3 àš˜à©°àšŸà©‡ àšŠà©‡ àš…à©°àšŠàš°-àš…à©°àšŠàš° àščੀ àšžà©‹àš§àšżàš† àšœàšŸ àšžàš•àšŠàšŸ àščà©ˆà„€", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àš‡àšž àšžà©àššà©‡àščੇ àššà©‚à©° àš­à©‡àšœà©‡ àšœàšŸàšŁ àš€à©‹àš‚ 24 àš˜à©°àšŸà©‡ àšŠà©‡ àš…à©°àšŠàš°-àš…à©°àšŠàš° àščੀ àš‡àšžàššà©‚à©° àšžà©‹àš§àšżàš† àšœàšŸ àšžàš•àšŠàšŸ àščà©ˆà„€", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àš‡àšč àšžà©àššà©‡àščàšŸ àšźàšżàšŸàšŸ àšŠàšżà©±àš€àšŸ àš—àšżàš† àšžà©€à„€", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àšŠàšżàš–àšŸàš‰àšŁ àšŠà©‡ àšČàšˆ àš…àšŸà©ˆàššàšźà©ˆàš‚àšŸ àšŹàščà©àš€ àš”à©±àšĄà©€ àščà©ˆà„€", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àšŠàšżàš–àšŸàš‰àšŁ àšŠà©‡ àšČàšˆ àš•à©àš àš…àšŸà©ˆàššàšźà©ˆàš‚àšŸàšŸàš‚ àšŹàščà©àš€ àš”à©±àšĄà©€àš†àš‚ àščàššà„€", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àšŠàšŸàšš àšŠà©‡ àš”à©‡àš°àš”à©‡ àšȘà©àš°àšŸàšȘàš€ àš•àš°àšš àš”àšżà©±àšš àš…àšžàšźàš°à©±àš„ àš°àščੇ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "àšžàšżàš°à©ž Signal àšŹà©€àšŸàšŸ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àšžà©àššà©‡àščàšżàš†àš‚ àššà©‚à©° àšžà©‹àš§àšŁ àšŠà©€ àšžàščੂàšČàš€ àšžàšżàš°àš«àšŒ Signal àšŹà©€àšŸàšŸ àšŠà©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš°àšŸàš‚ àšČàšˆ àš‰àšȘàšČàšŹàš§ àščà©ˆà„€ àšœà©‡àš•àš° àš€à©àšžà©€àš‚ àš•àšżàšžà©‡ àšžà©àššà©‡àščੇ àššà©‚à©° àšžà©‹àš§àšŠà©‡ àščੋ, àš€àšŸàš‚ àš‡àšč àšžàšżàš°àš«àšŒ àš‰àščàššàšŸàš‚ àšČà©‹àš•àšŸàš‚ àššà©‚à©° àšŠàšżàš–àšŸàšˆ àšŠà©‡àš”à©‡àš—àšŸ àšœàšżàščàššàšŸàš‚ àš•à©‹àšČ Signal àšŹà©€àšŸàšŸ àšŠàšŸ àššàš”àšŸàš‚ àš”àš°à©›àšš àščà©ˆà„€", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àšžà©àššà©‡àščੇ àššà©‚à©° àšžà©‹àš§à©‹", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àšœà©‡àš•àš° àš€à©àšžà©€àš‚ àš•àšżàšžà©‡ àšžà©àššà©‡àščੇ àššà©‚à©° àšžà©‹àš§àšŠà©‡ àščੋ, àš€àšŸàš‚ àš‡àšč àšžàšżàš°àš«àšŒ àš‰àščàššàšŸàš‚ àšČà©‹àš•àšŸàš‚ àššà©‚à©° àšŠàšżàš–àšŸàšˆ àšŠà©‡àš”à©‡àš—àšŸ àšœàšżàščàššàšŸàš‚ àš•à©‹àšČ Signal àšŠàšŸ àššàš”àšŸàš‚ àš”àš°à©›àšš àščà©ˆà„€ àš‰àšč àš‡àšč àšŠà©‡àš– àšžàš•àšŁàš—à©‡ àš•àšż àš€à©àšžà©€àš‚ àšžà©àššà©‡àščàšŸ àšžà©‹àš§àšżàš† àščà©ˆà„€", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àš”à©€àšĄà©€àš“ àš•àšŸàšČ àš† àš°àščੀ àščੈ ", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àš†àšŠàšŸàš—à©‹àš‡à©°àš— àš”à©Œàš‡àšž àš•àšŸàšČ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àšœàšŸàš°à©€ àš”à©€àšĄà©€àš“ àš•àšŸàšČ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àš€à©àščàšŸàššà©‚à©° àš•àšŸàšČ àš•àš° àš°àščੇ àščàšš", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àšźà©à©œ-àš•àššà©ˆàš•àšŸ àš•à©€àš€àšŸ àšœàšŸ àš°àšżàščàšŸ àščੈ ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} àš”àšżàš…àš•àš€à©€} other {{count,number} àšČà©‹àš•}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àš†àšĄà©€àš“ àš•àšŸàšČ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àš•à©±àšŸà©‹", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àš•àšŸàšČ àššà©‚à©° àš›à©±àšĄà©‹", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àšźàšŸàšˆàš• àšŹà©°àšŠ àščੈ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àšźàšŸàšˆàš• àššàšŸàšČੂ àščੈ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àš°àšżà©°àš— àššàšŸàšČੂ àščੈ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àš°àšżà©°àš— àšŹà©°àšŠ àščੈ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àšžà©ˆàšŸàšżà©°àš—àšŸàš‚", @@ -3468,13 +3668,25 @@ "messageformat": "àšȘà©‚àš°à©€ àšžàš•àš°à©€àšš àš‰à©±àš€à©‡ àš•àšŸàšČ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àš—àš°àšżà©±àšĄ àšŠà©àš°àšżàš¶ àšČàšˆ àšŹàšŠàšČੋ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àš”àšżàšŠ àšŹàšŠàšČੋ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àšžàšȘà©€àš•àš° àšŠà©àš°àšżàš¶ àšČàšˆ àšŹàšŠàšČੋ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àš—àš°àšżà©±àšĄ àš”àšżàšŠ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àšžàšŸàšˆàšĄàšŹàšŸàš° àš”àšżàšŠ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àšžàšȘà©€àš•àš° àš”àšżàšŠ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àš”àšżàšŠ àš…à©±àšȘàšĄà©‡àšŸ àš•à©€àš€àšŸ àš—àšżàš†", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àš•àšŸàšČ àššà©‚à©° àš›à©±àšĄà©‹", @@ -3576,6 +3788,14 @@ "messageformat": "àš à©€àš• àščੈ", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àšžà©àššà©‡àščàšŸ àšžà©‹àš§àšżàš† àššàščà©€àš‚ àšœàšŸ àšžàš•àšŠàšŸ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àš‡àšž àšžà©àššà©‡àščੇ àššà©‚à©° àšžàšżàš°àš«àšŒ {max,number} àš”àšŸàš° àšžà©‹àš§àšżàš† àšœàšŸ àšžàš•àšŠàšŸ àščà©ˆà„€", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àš…à©žàšžà©‹àšž, àš‰àšž sgnl:// àšČàšżà©°àš• àšŠàšŸ àš•à©‹àšˆ àš…àš°àš„ àššàščà©€àš‚ àšŹàšŁàšŠàšŸ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àš”àš°àš€à©‹àš‚àš•àšŸàš°-àššàšŸàš‚", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àš€à©àščàšŸàšĄà©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšŠà©‡ àššàšŸàšČ àš•à©àš àš—àšČàš€ àš”àšŸàšȘàš° àš—àšżàš† àščੈ, àš‡àšč àščà©àšŁ àš€à©àščàšŸàšĄà©‡ àš–àšŸàš€à©‡ àššà©‚à©° àš…àšžàšŸàšˆàšš àššàščà©€àš‚ àš•à©€àš€àšŸ àš—àšżàš† àščà©ˆà„€", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àščàšŸàšŸàš“", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àšŻà©‚àšœàšŒàš°àššà©‡àšź àšžàšżàš°àšœà©‹", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR àš•à©‹àšĄ àšœàšŸàš‚ àšČàšżà©°àš•", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àššà©‚à©° àš°à©€àšžà©ˆà©±àšŸ àš•àš°àšš àšŠà©€ àšČੋੜ àščੈ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšŠà©‡ àšČàšżà©°àš• àššà©‚à©° àš°à©€àšžà©ˆà©±àšŸ àš•àš°àšš àšŠà©€ àšČੋੜ àščੈ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àš†àšȘàšŁàšŸ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšžàšŸàš‚àšàšŸ àš•àš°à©‹", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àščàšŸàšŸàš“", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àš…àšœàšżàščàšŸ àš•àš°àšš àššàšŸàšČ àš€à©àščàšŸàšĄàšŸ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àščàšŸàšŸ àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸ àš…àš€à©‡ àšŠà©‚àšœà©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš° àš‰àšž àššàšŸàš‚ àššà©‚à©° àš•àšČà©‡àšź àš•àš° àšžàš•àšŁàš—à©‡à„€ àš•à©€ àš€à©àšžà©€àš‚ àšȘà©±àš•àšŸ àš‡àšč àš•àš°àššàšŸ àššàšŸàščà©à©°àšŠà©‡ àščੋ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àš…àšœàšżàščàšŸ àš•àš°àšš àššàšŸàšČ àš€à©àščàšŸàšĄà©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àššà©‚à©° àščàšŸàšŸ àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸ àš…àš€à©‡ àš€à©àščàšŸàšĄà©‡ QR àš•à©‹àšĄ àš…àš€à©‡ àšČàšżà©°àš• àššà©‚à©° àš…àšžàšźàš°à©±àš„ àš•àš° àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸà„€ “{username}” àšŠà©‚àšœà©‡ àš”àš°àš€à©‹àš‚àš•àšŸàš° àš”àšŸàšžàš€à©‡ àš•àšČà©‡àšź àš•àš°àšš àšČàšˆ àš‰àšȘàšČàšŹàš§ àščੋ àšœàšŸàš”à©‡àš—àšŸà„€ àš•à©€ àš€à©àšžà©€àš‚ àšȘà©±àš•àšŸ àš…àšœàšżàščàšŸ àš•àš°àššàšŸ àššàšŸàščà©à©°àšŠà©‡ àščੋ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àščà©àšŁ àš€à©àšžà©€àš‚ àššàšŸ àščੀ àšžàšŸà©‹àš°à©€àš†àš‚ àššà©‚à©° àšžàšŸàš‚àšàšŸ àš•àš° àšžàš•à©‹àš—à©‡ àš…àš€à©‡ àššàšŸ àščੀ àšŠà©‡àš– àšžàš•à©‹àš—à©‡à„€ àš€à©àščàšŸàšĄà©‡ àš”à©±àšČà©‹àš‚ àščàšŸàšČ àščੀ àš”àšżà©±àšš àšžàšŸàš‚àšà©‡ àš•à©€àš€à©‡ àš—àš àšžàšŸà©‹àš°à©€ àš…à©±àšȘàšĄà©‡àšŸ àš”à©€ àšźàšżàšŸàšŸ àšŠàšżà©±àš€à©‡ àšœàšŸàšŁàš—à©‡à„€", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àš­àšŸàšžàšŒàšŸ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àš­àšŸàšžàšŒàšŸ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àšžàšżàšžàšŸàšź àšŠà©€ àš­àšŸàšžàšŒàšŸ", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àš­àšŸàšžàšŒàšŸàš”àšŸàš‚ àš–à©‹àšœà©‹", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” àšČàšˆ àš•à©‹àšˆ àššàš€à©€àšœà©‡ àššàščà©€àš‚ àšźàšżàšČੇ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àšžà©ˆà©±àšŸ àš•àš°à©‹", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àšČàšŸàš—à©‚ àš•àš°àšš àšČàšˆ Signal àšźà©à©œ àššàšŸàšČੂ àš•àš°à©‹", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àš­àšŸàšžàšŒàšŸ àšŹàšŠàšČàšŁ àšČàšˆ, àšàšȘ àššà©‚à©° àšźà©à©œ àššàšŸàšČੂ àš•àš°àšš àšŠà©€ àšČੋੜ àščà©ˆà„€", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àšźà©à©œ àššàšŸàšČੂ àš•àš°à©‹", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version}àš”àš°à©›àšš àšČàšˆ àš…à©±àšȘàšĄà©‡àšŸ àšźà©Œàšœà©‚àšŠ àščੈ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àš€à©àščàšŸàšĄà©€àš†àš‚ àšžà©ˆàšŸàšżà©°àš—àšŸàš‚ àššà©‚à©° àšžà©‡àš” àš•àš°àšŠà©‡ àšžàšźà©‡àš‚ àš•à©àš‡à©±àš•à©‹àšˆ àš—à©œàšŹà©œà©€ àšȘà©‡àš¶ àš† àš—àšˆ àšžà©€à„€ àš•àšżàš°àšȘàšŸ àš•àš°àš•à©‡ àšŠà©àšŹàšŸàš°àšŸ àš•à©‹àšžàšŒàšżàšž àš•àš°à©‹à„€", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àšžà©àššà©‡àščàšŸ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àščà©‹àš° àšžàšŒà©ˆàšČà©€àš†àš‚", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àšźà©à©œ-àšžà©ˆà©±àšŸ àš•àš°à©‹", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àšźà©àš•à©°àšźàšČ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšČàšżà©°àš• àšŠàšŸ àš°à©°àš—, {total,number} àš”àšżà©±àššà©‹àš‚ {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àšœà©‡àš•àš° àš€à©àšžà©€àš‚ àš†àšȘàšŁàšŸ QR àš•à©‹àšĄ àš°à©€àšžà©ˆà©±àšŸ àš•àš°àšŠà©‡ àščੋ, àš€àšŸàš‚ àš€à©àščàšŸàšĄàšŸ àšźà©Œàšœà©‚àšŠàšŸ QR àš•à©‹àšĄ àš…àš€à©‡ àšČàšżà©°àš• àš•à©°àšź àššàščà©€àš‚ àš•àš°à©‡àš—àšŸà„€", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àšČàšżà©°àš• àš°à©€àšžà©ˆà©±àšŸ àš•à©€àš€àšŸ àšœàšŸ àš°àšżàščàšŸ àščੈ ", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR àš•à©‹àšĄ àš…àš€à©‡ àšČàšżà©°àš• àšžà©ˆà©±àšŸ àššàščà©€àš‚ àščà©ˆà„€ àš†àšȘàšŁà©‡ àššà©ˆà©±àšŸàš”àš°àš• àš•àššà©ˆàš•àšžàšŒàšš àšŠà©€ àšœàšŸàš‚àšš àš•àš°à©‹ àš…àš€à©‡ àšŠà©àšŹàšŸàš°àšŸ àš•à©‹àšžàšŒàšżàšžàšŒ àš•àš°à©‹à„€", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àš†àšȘàšŁàšŸ Signal àš”àš°àš€à©‹àš‚àš•àšŸàš° àššàšŸàš‚ àšžà©ˆà©±àšŸ àš•àš°à©‹", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "àšŠà©àšŹàšŸàš°àšŸ àš­à©‡àšœà©‹", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àščà©‹àš° àš•àšŸàš°àš”àšŸàšˆàš†àš‚", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àš•àšŸàšČàšŸàš‚", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àššàš”à©€àš‚ àš•àšŸàšČ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àššàš”à©€àš‚ àš•àšŸàšČ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àščà©‹àš° àš•àšŸàš°àš”àšŸàšˆàš†àš‚", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àš•àšŸàšČ àš‡àš€àšżàščàšŸàšž àššà©‚à©° àšźàšżàšŸàšŸàš“", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àš•à©€ àš•àšŸàšČ àš‡àš€àšżàščàšŸàšž àššà©‚à©° àšźàšżàšŸàšŸàš‰àšŁàšŸ àščੈ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àš…àšœàšżàščàšŸ àš•àš°àšš 'àš€à©‡ àš•àšŸàšČ àš‡àš€àšżàščàšŸàšž àššà©‚à©° àšžàš„àšŸàšˆ àš€à©Œàš° 'àš€à©‡ àšźàšżàšŸàšŸ àšŠàšżà©±àš€àšŸ àšœàšŸàš”à©‡àš—àšŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àšźàšżàšŸàšŸàš“", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àš•àšŸàšČ àš‡àš€àšżàščàšŸàšž àšźàšżàšŸàšŸàš‡àš† àš—àšżàš†", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àš•àšŸàšČ àšŠà©‡àš–àšŁ àšœàšŸàš‚ àšžàšŒà©àš°à©‚ àš•àš°àšš àšČàšˆ àš•àšČàšżà©±àš• àš•àš°à©‹", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àš–à©‹àšœà©‹", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àšźàšżàšžàšĄ àš•àšŸàšČàšŸàš‚ àš…àššà©àšžàšŸàš° àš«àšżàšČàšŸàš° àš•à©€àš€àšŸ àš—àšżàš†", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àšŹàšŠàšČੋ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àš•à©‹àšˆ àščàšŸàšČà©€àš† àš•àšŸàšČàšŸàš‚ àšźà©Œàšœà©‚àšŠ àššàščà©€àš‚ àščàššà„€ àš•àšżàšžà©‡ àšŠà©‹àšžàš€ àššà©‚à©° àš•àšŸàšČ àš•àš°àš•à©‡ àšžàšŒà©àš°à©‚àš†àš€ àš•àš°à©‹à„€", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” àšČàšˆ àš•à©‹àšˆ àššàš€à©€àšœà©‡ àššàščà©€àš‚ àšźàšżàšČੇ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àš‡àššàš•àšźàšżà©°àš— àš•àšŸàšČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àš†àšŠàšŸàš—à©‹àš‡à©°àš— àš•àšŸàšČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àšźàšżàšžàšĄ àš•àšŸàšČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àš—àš°à©à©±àšȘ àš•àšŸàšČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àš•à©‹àšˆ àščàšŸàšČà©€àš† àš—à©±àšČàšŹàšŸàš€ àšźà©Œàšœà©‚àšŠ àššàščà©€àš‚ àščà©ˆà„€", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” àšČàšˆ àš•à©‹àšˆ àššàš€à©€àšœà©‡ àššàščà©€àš‚ àšźàšżàšČੇ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àš†àšŠàšŸàš—à©‹àš‡à©°àš— àš”à©Œàš‡àšž àš•àšŸàšČ} other {àš‡àššàš•àšźàšżà©°àš— àš”à©Œàš‡àšž àš•àšŸàšČ}}} Video {{direction, select, Outgoing {àšœàšŸàš°à©€ àš”à©€àšĄà©€àš“ àš•àšŸàšČ} other {àš† àš°àščੀ àš”à©€àšĄà©€àš“ àš•àšŸàšČ}}} Group {{direction, select, Outgoing {àš†àšŠàšŸàš—à©‹àš‡à©°àš— àš—àš°à©à©±àšȘ àš•àšŸàšČ} other {àš‡àššàš•àšźàšżà©°àš— àš—àš°à©à©±àšȘ àš•àšŸàšČ}}} other {{direction, select, Outgoing {àšŹàšŸàščàš° àšœàšŸàšŁ àš”àšŸàšČੀ àš•àšŸàšČ} other {àš†àš‰àšŁ àš”àšŸàšČੀ àš•àšŸàšČ }}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àš”à©Œàš‡àšž àš•àšŸàšČ àšźàšżàšž àščà©‹àšˆ} Video {àš–à©à©°àšà©€ àš”à©€àšĄà©€àš“ àš•àšŸàšČ} Group {àšźàšżàšž àščà©‹àšˆàš†àš‚ àš—àš°à©à©±àšȘ àš•àšŸàšČ} other {àšźàšżàšžàšĄ àš•àšŸàšČ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àš”à©Œàš‡àšž àš•àšŸàšČ àššàščà©€àš‚ àššà©à©±àš•à©€ àš—àšˆ} Video {àšœàš”àšŸàšŹ àššàšŸ àšŠàšżà©±àš€à©€ àš”à©€àšĄà©€àš“ àš•àšŸàšČ} Group {àš—àš°à©à©±àšȘ àš•àšŸàšČ àššàščà©€àš‚ àššà©à©±àš•à©€ àš—àšˆ} other {àš•àšŸàšČ àššàščà©€àš‚ àššà©à©±àš•à©€ àš—àšˆ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àš”à©Œàš‡àšž àš•àšŸàšČ àššà©‚à©° àš…àšžàš”à©€àš•àšŸàš° àš•à©€àš€àšŸ àš—àšżàš†} Video {àš”à©€àšĄà©€àš“ àš•àšŸàšČ àššà©‚à©° àš…àšžàš”à©€àš•àšŸàš° àš•à©€àš€àšŸ àš—àšżàš†} Group {àš—àš°à©à©±àšȘ àš•àšŸàšČ àššà©‚à©° àš…àšžàš”à©€àš•àšŸàš° àš•à©€àš€àšŸ àš—àšżàš†} other {àš•àšŸàšČ àššà©‚à©° àš…àšžàš”à©€àš•àšŸàš° àš•à©€àš€àšŸ àš—àšżàš†}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} àščà©‹àš° àš”àš°àš€à©‹àš‚àš•àšŸàš° àšČàšżàš– àš°àšżàščàšŸ àščà©ˆà„€} other {{count,number} àščà©‹àš° àš”àš°àš€à©‹àš‚àš•àšŸàš° àšČàšżàš– àš°àščੇ àščàššà„€}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àššàš”àšŸàš‚ àš•à©€ àščੈ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àš›à©‹àšŸà©‡-àšźà©‹àšŸà©‡ àšžà©àš§àšŸàš°, à©™àš°àšŸàšŹà©€àš†àš‚ àššà©‚à©° àšŠàš°à©àšžàš€ àš…àš€à©‡ àšȘà©àš°àšŠàš°àšžàšŒàšš àššà©‚à©° àšŹàšżàščàš€àš° àšŹàšŁàšŸàš‡àš† àš—àšżàš† àščà©ˆà„€ Signal àšŠà©€ àš”àš°àš€à©‹àš‚ àš•àš°àšš àšČàšˆ àš€à©àščàšŸàšĄàšŸ àš§à©°àššàš”àšŸàšŠ!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àš‡àšž àš…à©±àšȘàšĄà©‡àšŸ àš”àšżà©±àšš àš”à©Œàš‡àšž àš…àš€à©‡ àš”à©€àšĄà©€àš“ àš•àšŸàšČàšŸàš‚ àšČàšˆ àš•à©àš àšžà©àš§àšŸàš° àš…àš€à©‡ àš•à©àš àšźàšŸàšźà©‚àšČੀ àšŠàšžàš€àšŸàš”à©‡à©›à©€ àš…à©±àšȘàšĄà©‡àšŸàšŸàš‚ àšžàšŒàšŸàšźàšČ àščàšš (àš§à©°àššàš”àšŸàšŠ, {linkToGithub}!)à„€" + "icu:WhatsNew__v6.39--0": { + "messageformat": "àščà©àšŁ àš€à©àšžà©€àš‚ àš†àšȘàšŁà©€àš†àš‚ àšžàšżàšžàšŸàšź àšžà©ˆàšŸàšżà©°àš—àšŸàš‚ àššà©‚à©° àšŹàšŠàšČੇ àšŹàšżàššàšŸàš‚ Signal àš”àšżà©±àšš àš†àšȘàšŁà©€ àššà©àšŁà©€ àščà©‹àšˆ àš­àšŸàšžàšŒàšŸ àššà©‚à©° àšŹàšŠàšČ àšžàš•àšŠà©‡ àščੋ (Signal àšžà©ˆàšŸàšżà©°àš—àšŸàš‚ > àšŠàšżà©±àš– > àš­àšŸàšžàšŒàšŸ)à„€" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àš…àšžà©€àš‚ àš—àš°à©à©±àšȘ àšžà©‚àššàššàšŸ àšŠà©‡ àš†àšˆàš•àššàšŸàš‚ àššà©‚à©° àšžà©‹àš§àšżàš† àščà©ˆà„€" + "icu:WhatsNew__v6.39--1": { + "messageformat": "àš…àšžà©€àš‚ macOS 'àš€à©‡ àš•àšŸàšČ àšČàšŸàšŹà©€ àš”àšżà©±àšš àšžàšŒàšŸàšźàšČ àščà©‹àšŁ àšŠà©Œàš°àšŸàšš àščà©‹àšŁ àš”àšŸàšČੀ àš„à©‹à©œà©àščੀ àšœàšżàščੀ àšŠà©‡àš°à©€ àššà©‚à©° àš à©€àš• àš•à©€àš€àšŸ àščà©ˆà„€" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àš…àšžà©€àš‚ àš”à©€àšĄà©€àš“ àšŸàšŸàšˆàšČàšŸàš‚ àšČàšˆ àšŸà©àš°àšŸàš‚àšœà©€àš¶àšš àšàššà©€àšźà©‡àšžàšŒàšš àššà©‚à©° àš à©€àš• àš•à©€àš€àšŸ àščੈ, àšœàšŠà©‹àš‚ àš•à©‹àšˆ àš—àš°à©à©±àšȘ àš•àšŸàšČ àš”àšżà©±àšš àšžàšŒàšŸàšźàšČ àščà©à©°àšŠàšŸ àščੈ àšœàšŸàš‚ àš•àšŸàšČ àššà©‚à©° àš›à©±àšĄ àš•à©‡ àšœàšŸàš‚àšŠàšŸ àščà©ˆà„€" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àščà©àšŁ àš€à©àšžà©€àš‚ àššà©ˆàšŸ àšžà©ˆàšŸàšżà©°àš—àšŸàš‚ àššà©‚à©° àš€à©‡àšœàšŒà©€ àššàšŸàšČ àšàš•àšžà©ˆàšž àš•àš°àšš àšČàšˆ àšœàšŸàš‚ àš‰àšž àššà©ˆàšŸ àš€à©‹àš‚ àš•àšżàšžà©‡ àš”à©€ àš…àšŁàšŠà©‡àš–à©€ àš•àščàšŸàšŁà©€àš†àš‚ àššà©‚à©° àšŠà©‡àš–àšŁ àšČàšˆ àššà©ˆàšŸ àščà©ˆàšĄàš° àš”àšżà©±àšš àšȘà©àš°à©‹à©žàšŸàšˆàšČ à©žà©‹àšŸà©‹ àšœàšŸàš‚ àš—àš°à©à©±àšȘ àš…àš”àš€àšŸàš° 'àš€à©‡ àš•àšČàšżà©±àš• àš•àš° àšžàš•àšŠà©‡ àščà©‹à„€ àš§à©°àššàš”àšŸàšŠ, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index 01c32d808e..2ef8e2a41e 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "BƂąd bazy danych", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "WystąpiƂ bƂąd bazy danych. MoĆŒesz skopiować bƂąd i skontaktować się z dziaƂem wsparcia Signal, by uzyskać pomoc w jego naprawieniu. Jeƛli musisz skorzystać z aplikacji Signal juĆŒ teraz, moĆŒesz usunąć swoje dane i uruchomić ponownie.\n\nSkontaktuj się z dziaƂem wsparcia, przechodząc pod adres: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "UsuƄ wszystkie dane i uruchom ponownie", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "UsuƄ dane i zrestartuj", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Trwale usunąć wszystkie dane?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Twoja caƂa historia wiadomoƛci i media zostaną trwale usunięte z tego urządzenia. Będziesz mĂłgƂ/mogƂa uĆŒywać aplikacji Signal na tym urządzeniu po jej ponownym poƂączeniu. Operacja ta nie spowoduje usunięcia ĆŒadnych danych na Twoim telefonie.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Wersja Twojej bazy danych jest niezgodna z tą wersją aplikacji Signal. Upewnij się, ĆŒe otwierasz najnowszą wersję Signal na swoim komputerze.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Plik", @@ -300,6 +316,70 @@ "messageformat": "Czaty", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "WystąpiƂ bƂąd związany z Twoją nazwą uĆŒytkownika – nie jest juĆŒ przypisana do Twojego konta. MoĆŒesz sprĂłbować ustawić ją ponownie lub wybrać nową nazwę.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Napraw bƂąd teraz", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Coƛ poszƂo nie tak z kodem QR i linkiem z nazwą uĆŒytkownika – jest niewaĆŒny. UtwĂłrz nowy link do udostępniania innym.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Napraw bƂąd teraz", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "PokaĆŒ karty", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ukryj karty", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "WystąpiƂ bƂąd", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "Nieprzeczytanych: {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Oznaczona jako nieprzeczytana", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Czaty", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "PoƂączenia", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Relacje", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Ustawienia", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Zaktualizuj Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Wróć", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Te czaty są zarchiwizowane i pojawią się w skrzynce odbiorczej tylko po otrzymaniu nowych wiadomoƛci.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -513,7 +593,7 @@ "description": "Shown on the safety number screen when the user has selected to verify/unverify a contact's safety number, and we immediately discover a safety number change" }, "icu:safetyNumberChangeDialog__message": { - "messageformat": "Następujące osoby mogƂy ponownie zainstalować aplikację Signal albo zmienić urządzenie. Kliknij odbiorcę, aby potwierdzić nowy number bezpieczeƄstwa. Ta czynnoƛć jest opcjonalna.", + "messageformat": "Następujące osoby mogƂy ponownie zainstalować aplikację Signal albo zmienić urządzenie. Kliknij odbiorcę, aby potwierdzić nowy numer bezpieczeƄstwa. Ta czynnoƛć jest opcjonalna.", "description": "Shown on confirmation dialog when user attempts to send a message" }, "icu:safetyNumberChangeDialog__pending-messages": { @@ -576,6 +656,10 @@ "messageformat": "ZadzwoƄ mimo to", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "DoƂącz mimo to", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Kontynuuj rozmowę", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Numery bezpieczeƄstwa otrzymują aktualizację.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Dowiedz się więcej", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Poprzedni numer bezpieczeƄstwa", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Następny numer bezpieczeƄstwa", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Wersja numeru bezpieczeƄstwa, {index,number} z {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Oznacz jako zweryfikowany", @@ -663,33 +747,41 @@ "messageformat": "Wycofaj weryfikację", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "W celu zweryfikowania szyfrowania metodą end-to-end z uĆŒytkownikiem {name} porĂłwnaj powyĆŒsze numery z numerami na urządzeniu tej osoby. UĆŒytkownik moĆŒe teĆŒ zeskanować TwĂłj kod za pomocą swojego urządzenia.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Dowiedz się więcej", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Aby zweryfikować szyfrowanie metodą end-to-end z uĆŒytkownikiem {name}, dopasuj numery z kolorowej karty powyĆŒej do numerĂłw na urządzeniu tej osoby. Jeƛli numery się nie zgadzają, porĂłwnaj inną parę numerĂłw bezpieczeƄstwa. Wystarczy, ĆŒe pasuje jedna para.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "W celu zweryfikowania szyfrowania metodą end-to-end z uĆŒytkownikiem {name} porĂłwnaj powyĆŒsze numery z numerami na urządzeniu tej osoby. UĆŒytkownik moĆŒe teĆŒ zeskanować TwĂłj kod za pomocą swojego urządzenia.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Zmiany w numerach bezpieczeƄstwa", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Numery bezpieczeƄstwa będą aktualizowane przez pewien czas, by umoĆŒliwić wprowadzenie nadchodzących funkcji prywatnoƛci do Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Aby zweryfikować numery bezpieczeƄstwa, dopasuj numery z kolorowej karty do numerĂłw na urządzeniu Twojego kontaktu. Jeƛli numery się nie zgadzają, porĂłwnaj inną parę numerĂłw bezpieczeƄstwa. Wystarczy, ĆŒe pasuje jedna para.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Potrzebujesz pomocy?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Rozumiem", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Numer bezpieczeƄstwa zostanie stworzony dla tej osoby po tym, jak wymienicie wiadomoƛci.", @@ -1267,10 +1359,6 @@ "messageformat": "PokaĆŒ ostatnie multimedia", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Aby sprawdzić bezpieczeƄstwo szyfrowanego poƂączenia z uĆŒytkownikiem {name}, porĂłwnaj powyĆŒsze numery z numerami na urządzeniu tej osoby. UĆŒytkownik moĆŒe teĆŒ zeskanować powyĆŒszy kod QR.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Nie wymieniono jeszcze ĆŒadnych wiadomoƛci. Numer bezpieczeƄstwa dla tego kontaktu będzie dostępny po wymianie pierwszej wiadomoƛci." }, @@ -1295,7 +1383,7 @@ "description": "Shown on the drop-down menu for an individual message, opens the conversation in select mode with the current message selected" }, "icu:MessageTextRenderer--spoiler--label": { - "messageformat": "ZasƂonięte", + "messageformat": "Spoiler", "description": "Used as a label for screenreaders on 'spoiler' text, which is hidden by default" }, "icu:retrySend": { @@ -1334,17 +1422,17 @@ "messageformat": "Informacje", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "UsuƄ", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "UsuƄ wiadomoƛci", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Usunąć czat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Usunąć wiadomoƛci?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Ten czat zostanie usunięty z tego urządzenia.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Wiadomoƛci z tego czatu zostaną skasowane z tego urządzenia. Po skasowaniu wiadomoƛci wciÄ…ĆŒ będziesz mieć moĆŒliwoƛć wyszukania tego czatu.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Opuƛć grupę", @@ -1438,6 +1526,14 @@ "messageformat": "Twoja historia wiadomoƛci dla obu czatĂłw zostaƂa poƂączona tutaj.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} naleĆŒy do {conversationTitle}. Oboje naleĆŒycie do {sharedGroup}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} naleĆŒy do {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura obrazu z cytowanej wiadomoƛci", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ZadzwoƄ ponownie", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "PoƂącz", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "DoƂącz", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon wyciszony ze względu na liczbę uczestnikĂłw poƂączenia", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Powiadomienia o poƂączeniach", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "PoƂączenie jest peƂne", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "DoƂącz", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Rozpocznij", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "PoƂączenie peƂne", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera wyƂączona", @@ -1621,10 +1725,6 @@ "messageformat": "WƂącz kamerę", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Wycisz", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon wyƂączony", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Cofnij wyciszenie mikrofonu", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Udostępnij", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Udostępnianie wyƂączone", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "PrzestaƄ udostępniać", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ZadzwoƄ", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupa jest zbyt duĆŒa, aby powiadomić uczestnikĂłw dzwonkiem.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "WƂącz dzwonek", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "WyƂącz dzwonek", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "WƂącz dzwonek", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Więcej opcji", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Ty", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Twoja kamera jest wyƂączona", "description": "Label in the calling lobby indicating that your camera is off" @@ -2144,11 +2256,15 @@ "description": "A notification shown in a group conversation when a contact reinstalls, showing the contact name" }, "icu:ConversationDetails__viewSafetyNumber": { - "messageformat": "Zobacz number bezpieczeƄstwa", + "messageformat": "Zobacz numer bezpieczeƄstwa", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Wyƛlij wiadomoƛć", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { - "messageformat": "Zobacz number bezpieczeƄstwa", + "messageformat": "Zobacz numer bezpieczeƄstwa", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" }, "icu:cannotGenerateSafetyNumber": { @@ -2235,8 +2351,8 @@ "messageformat": "Nie udaƂo się wyszukać numeru telefonu. SprawdĆș poƂączenie z internetem i sprĂłbuj ponownie.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Edycji moĆŒna dokonać tylko w przeciągu 3 godzin od wysƂania wiadomoƛci.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Edycji moĆŒna dokonać tylko w przeciągu 24 godzin od wysƂania wiadomoƛci.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ta wiadomoƛć zostaƂa usunięta.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ZaƂącznik jest zbyt duĆŒy, ĆŒeby go wyƛwietlić.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "NiektĂłre zaƂączniki są zbyt duĆŒe, ĆŒeby je wyƛwietlić.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nie moĆŒna pobrać szczegóƂów darowizny", "description": "Aria label for donation when we can't fetch the details." @@ -3013,7 +3137,7 @@ "description": "Description of command to bold text in composer" }, "icu:Keyboard--composer--spoiler": { - "messageformat": "ZasƂoƄ zaznaczony tekst", + "messageformat": "Ukryj zaznaczony tekst", "description": "Description of command to bold text in composer" }, "icu:Keyboard--open-context-menu": { @@ -3037,7 +3161,7 @@ "description": "Shown when you hover over the bold button in the popup formatting menu" }, "icu:FormatMenu--guide--spoiler": { - "messageformat": "ZasƂonięte", + "messageformat": "Spoiler", "description": "Shown when you hover over the bold button in the popup formatting menu" }, "icu:Keyboard--scroll-to-top": { @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Tylko w Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Edytowanie wiadomoƛci to funkcja dostępna tylko dla uĆŒytkownikĂłw Signal beta. Twoje zmiany w wiadomoƛci będą widoczne wyƂącznie u osĂłb, ktĂłre uĆŒywają najnowszej wersji Signal beta", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Edytuj wiadomoƛć", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Twoje zmiany w wiadomoƛci będą widoczne wyƂącznie u osĂłb, ktĂłre uĆŒywają najnowszej wersji Signal. Osoby te będą mogƂy zobaczyć Twoją edycję wiadomoƛci.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Przychodzące poƂączenie wideo
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Wychodzące poƂączenie gƂosowe", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Wychodzące poƂączenie wideo", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} dzwoni do Ciebie", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Ponowne Ƃączenie
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} osoba} few {{count,number} osoby} many {{count,number} osĂłb} other {{count,number} osoby}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "PoƂączenie audio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ZakoƄcz", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Opuƛć", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon wyƂ.", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon wƂ.", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Dzwonek wƂ.", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Dzwonek wyƂ.", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Ustawienia", @@ -3468,13 +3668,25 @@ "messageformat": "PeƂny ekran", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "PrzeƂącz na widok siatki", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ZmieƄ widok", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "PrzeƂącz na aktualnie mĂłwiącego", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Siatka", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Pasek boczny", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Osoba mĂłwiąca", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Widok zaktualizowany", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Opuƛć rozmowę", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Nie moĆŒna edytować wiadomoƛci", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Tę wiadomoƛć moĆŒna edytować tylko {max,number} razy.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Przykro nam, ten link sgnl:// nie ma sensu!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nazwa uĆŒytkownika", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "WystąpiƂ bƂąd związany z Twoją nazwą uĆŒytkownika – nie jest juĆŒ przypisana do Twojego konta.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "UsuƄ nazwę uĆŒytkownika", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "UtwĂłrz nazwę uĆŒytkownika", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Kod QR lub link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Nazwa uĆŒytkownika wymaga zresetowania", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Link z nazwą uĆŒytkownika wymaga zresetowania", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Udostępnij swoją nazwę uĆŒytkownika", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "UsuƄ nazwę uĆŒytkownika", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "To dziaƂanie usunie Twoją nazwę uĆŒytkownika i pozwoli uĆŒywać jej innemu uĆŒytkownikowi. Na pewno chcesz to zrobić?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Ta czynnoƛć spowoduje usunięcie Twojej nazwy uĆŒytkownika i dezaktywację kodu QR i linku. Inni uĆŒytkownicy będą mogli uĆŒyć nazwy „{username}”. Chcesz kontynuować?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Stracisz moĆŒliwoƛć udostępniania i wyƛwietlania relacji. Relacje niedawno udostępnione przez Ciebie rĂłwnieĆŒ zostaną usunięte.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Język", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Język", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Język systemu", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Szukaj językĂłw", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Brak wynikĂłw dla „{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Ustaw", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Aby zastosować, uruchom Signal ponownie", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Aby zmienić język, aplikacja musi zostać uruchomiona ponownie.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Zresetuj", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Dostępna jest aktualizacja do wersji {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Podczas zapisywania Twoich ustawieƄ wystąpiƂ bƂąd. SprĂłbuj ponownie.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Wiadomoƛć", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Więcej stylĂłw", "description": "Action button for switching up the clock styles" @@ -6477,7 +6753,7 @@ "description": "Notification test for outgoing story reactions but no name" }, "icu:Quote__story-unavailable": { - "messageformat": "Historia nie jest juĆŒ dostępna", + "messageformat": "Relacja nie jest juĆŒ dostępna", "description": "Label for when a story is not found" }, "icu:ContextMenu--button": { @@ -6532,6 +6808,10 @@ "messageformat": "Zresetuj", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Gotowe", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Kolor linku do nazwy uĆŒytkownika,{index,number} z {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Jeƛli zresetujesz kod QR, TwĂłj obecny kod QR i link nie będą dziaƂaƂy.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Resetowanie linku
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Kod QR i link nie zostaƂy ustawione. SprawdĆș poƂączenie z internetem i sprĂłbuj ponownie.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Ustaw swoją nazwę uĆŒytkownika w Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "edytowana", + "messageformat": "Edytowana", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Wyƛlij ponownie", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Więcej poleceƄ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "PoƂączenia", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nowe poƂączenie", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nowe poƂączenie", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Więcej poleceƄ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Wyczyƛć historię poƂączeƄ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Wyczyƛcić historię poƂączeƄ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "CaƂa historia poƂączeƄ zostanie permanentnie skasowana", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "UsuƄ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Lista poƂączeƄ zostaƂa wyczyszczona", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Kliknij, aby wyƛwietlić lub rozpocząć poƂączenie", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Szukaj", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtruj wedƂug nieodebranych", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "PrzeƂącz", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Brak ostatnich poƂączeƄ. ZadzwoƄ do kogoƛ.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Brak wynikĂłw dla „{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Przychodzące", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Wychodzące", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Nieodebrane", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "PoƂączenie grupowe", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Brak najnowszych konwersacji.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Brak wynikĂłw dla „{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Wychodzące poƂączenie gƂosowe} other {Przychodzące poƂączenie gƂosowe}}} Video {{direction, select, Outgoing {Wychodzące poƂączenie wideo} other {Przychodzące poƂączenie wideo}}} Group {{direction, select, Outgoing {Wychodzące poƂączenie grupowe} other {Nadchodzące poƂączenie grupowe}}} other {{direction, select, Outgoing {PoƂączenie wychodzące} other {PoƂączenie przychodzące}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Nieodebrane poƂączenie gƂosowe} Video {Nieodebrane poƂączenie wideo} Group {Nieodebrane poƂączenie grupowe} other {Nieodebrane poƂączenie}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Nieodebrane poƂączenie gƂosowe} Video {Nieodebrane poƂączenie wideo} Group {Nieodebrane poƂączenie grupowe} other {Nieodebrane poƂączenie}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Odrzucone poƂączenie gƂosowe} Video {Odrzucone poƂączenie wideo} Group {Odrzucone poƂączenie grupowe} other {Odrzucone poƂączenie}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} inna osoba pisze.} few {{count,number} inne osoby piszą.} many {{count,number} innych osĂłb pisze.} other {{count,number} innej osoby pisze.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Co nowego", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "MaƂe ulepszenia, poprawki bƂędĂłw i zwiększona funkcjonalnoƛć. Dzięki za korzystanie z Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ta aktualizacja obejmuje kilka usprawnieƄ poƂączeƄ gƂosowych i wideo oraz drobne aktualizacje dokumentacji (dzięki, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Teraz moĆŒna zmienić wybrany język w aplikacji Signal bez zmiany ustawieƄ systemowych (Ustawienia Signal > Wygląd > Język)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Zmodyfikowaliƛmy ikony powiadomieƄ wyƛwietlanych dla grupowych aktualizacji, np. o doƂączeniu nowego czƂonka. Te ikony poprawiają czytelnoƛć, zwƂaszcza jeƛli skrywasz się w mroku trybu ciemnego." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Naprawiliƛmy krĂłtkie opĂłĆșnienie, ktĂłre czasem występowaƂo w trakcie doƂączania do poƂączenia na urządzeniach z macOS, co powinno wyeliminować przynajmniej jedną z wymĂłwek dla póƂsekundowego spĂłĆșnienia na spotkanie." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Poprawiliƛmy efekt przejƛcia w kafelkach wideo — ten, ktĂłry uruchamia się, gdy ktoƛ doƂącza do poƂączenia grupowego lub je opuszcza. Angielskie wyjƛcie jeszcze nigdy nie byƂo tak proste." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Od teraz moĆŒesz kliknąć w zdjęcie profilowe lub awatar grupy w nagƂówku czatu, aby szybko uzyskać dostęp do ustawieƄ czatu lub wyƛwietlić wszystkie niewyƛwietlone relacje z tego czatu. Dzięki, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/pt-BR/messages.json b/_locales/pt-BR/messages.json index f72d6d8ff3..6e1ff3533c 100644 --- a/_locales/pt-BR/messages.json +++ b/_locales/pt-BR/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Erro no banco de dados", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ocorreu um erro de base de dados. Copie o erro e entre em contato com o suporte do Signal para resolver o problema. Se precisar usar o Signal imediatamente, exclua seus dados e reinicie.\n\nEntre em contato com o suporte aqui: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Excluir todos os dados e reiniciar", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Excluir dados e reiniciar", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Excluir todos os dados permanentemente?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Todo o seu histĂłrico de mensagens e mĂ­dia serĂŁo excluĂ­dos permanentemente deste dispositivo. VocĂȘ poderĂĄ usar o Signal neste dispositivo apĂłs vinculĂĄ-lo novamente. Os dados do seu telefone nĂŁo serĂŁo excluĂ­dos.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "A versĂŁo da sua base de dados nĂŁo corresponde a esta versĂŁo do Signal. Confira se estĂĄ abrindo a versĂŁo mais recente do Signal no seu computador.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Arquivo", @@ -300,6 +316,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Algo deu errado com seu nome de usuĂĄrio, pois ele nĂŁo estĂĄ mais atribuĂ­do Ă  sua conta. VocĂȘ pode tentar defini-lo de novo ou escolher outro.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Corrigir agora", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Algo deu errado com o QR code e link do seu nome de usuĂĄrio, ele nĂŁo Ă© mais vĂĄlido. Crie outro link para compartilhar com outras pessoas.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Corrigir agora", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Mostrar abas", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ocultar abas", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ocorreu um erro", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} nĂŁo lida(s)", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marcadas como nĂŁo lidas", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Chamadas", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ConfiguraçÔes", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Atualizar o Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Perfil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Voltar", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Esses chats estĂŁo arquivados e sĂł aparecerĂŁo na caixa de entrada se vocĂȘ receber novas mensagens.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ligar mesmo assim", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Entrar mesmo assim", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continuar a chamada", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Os nĂșmeros de segurança estĂŁo sendo atualizados.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Saiba mais", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "NĂșmero de segurança anterior", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "PrĂłximo nĂșmero de segurança", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "VersĂŁo do nĂșmero de segurança, {index,number} de {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marcar como verificado", @@ -663,33 +747,41 @@ "messageformat": "Apagar verificação", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Para verificar a criptografia de ponta a ponta com {name}, compare os nĂșmeros acima com os nĂșmeros no dispositivo dessa pessoa. TambĂ©m Ă© possĂ­vel escanear seu cĂłdigo com um dispositivo.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Saiba mais", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Para verificar a criptografia de ponta a ponta com {name}, combine o cartĂŁo de cor acima com o dispositivo e compare os nĂșmeros. Se nĂŁo corresponder, use o outro par de nĂșmeros de segurança. Apenas um par precisa dar match.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Para verificar a criptografia de ponta a ponta com {name}, compare os nĂșmeros acima com os nĂșmeros no dispositivo dessa pessoa. TambĂ©m Ă© possĂ­vel escanear seu cĂłdigo com um dispositivo.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "AlteraçÔes nos nĂșmeros de segurança", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Vamos atualizar os nĂșmeros de segurança durante um perĂ­odo de transição para habilitar os prĂłximos recursos de privacidade no Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Para verificar nĂșmeros de segurança, combine o cartĂŁo da cor com o dispositivo do seu contato. Se nĂŁo corresponder, use o outro par de nĂșmeros de segurança. Apenas um par precisa dar match.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Precisa de ajuda?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Entendi", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ApĂłs trocar mensagens com essa pessoa, um nĂșmero de segurança serĂĄ criado.", @@ -1267,10 +1359,6 @@ "messageformat": "Ver mĂ­dia recente", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Para verificar a segurança da sua criptografia de ponta a ponta com {name}, compare os nĂșmeros acima com os nĂșmeros no aparelho dessa pessoa. TambĂ©m Ă© possĂ­vel escanear o QR code acima.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "VocĂȘ ainda nĂŁo trocou nenhuma mensagem com este contato. O seu nĂșmero de segurança com ele estarĂĄ disponĂ­vel apĂłs a primeira mensagem." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Apagar", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Excluir mensagens", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Quer excluir o chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Apagar mensagens?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Este chat serĂĄ excluĂ­do do dispositivo.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "As mensagens neste chat serĂŁo excluĂ­das deste dispositivo. VocĂȘ pode pesquisar neste chat antes de excluir mensagens.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Sair do grupo", @@ -1438,6 +1526,14 @@ "messageformat": "Seu histĂłrico de mensagens para ambos os chats foi mesclado aqui.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pertence Ă  conversa {conversationTitle}. VocĂȘ sĂŁo membros do grupo {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pertence Ă  conversa {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura da imagem na citação", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ligar novamente", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Começar a chamada", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Participar da chamada", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Microfone silenciado devido Ă  quantidade de pessoas na chamada", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "NotificaçÔes de chamadas", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "A chamada estĂĄ lotada", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "CĂąmera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Entrar", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Começar", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Chamada lotada", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "CĂąmera desativada", @@ -1621,10 +1725,6 @@ "messageformat": "Ativar cĂąmera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silenciar", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microfone desativado", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ligar microfone", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Apresentar", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Apresentação desativada", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Parar apresentação", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ligar", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "O grupo Ă© muito grande para ligar para todos os participantes.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Ligar em vez de enviar notificação", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Desativar toque", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Ativar toque", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Mais opçÔes", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "VocĂȘ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Sua cĂąmera estĂĄ desligada", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Ver NĂșmero de Segurança", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Enviar mensagem", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Ver NĂșmero de Segurança", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Falha ao buscar o nĂșmero de telefone. Verifique a sua conexĂŁo e tente novamente.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "SĂł Ă© possĂ­vel fazer ediçÔes no perĂ­odo de '{'0'}' horas apĂłs enviar esta mensagem.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "SĂł Ă© possĂ­vel fazer ediçÔes no perĂ­odo de 24 horas apĂłs enviar esta mensagem.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Essa mensagem foi apagada.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "O anexo Ă© muito grande para ser exibido.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Alguns anexos sĂŁo muito grandes para serem exibidos.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "NĂŁo foi possĂ­vel obter os detalhes da doação", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Somente no Signal Beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "A edição de mensagens estĂĄ disponĂ­vel apenas para usuĂĄrios do Signal Beta. Se vocĂȘ editar uma mensagem, ela ficarĂĄ visĂ­vel para pessoas que estejam usando a versĂŁo mais recente do Signal Beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editar mensagem", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Se vocĂȘ editar uma mensagem, ela ficarĂĄ visĂ­vel para pessoas que estejam usando as versĂ”es mais recentes do Signal. Elas poderĂŁo ver que vocĂȘ editou a mensagem.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Recebendo chamada de vĂ­deo
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Chamada de voz efetuada", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Chamada de vĂ­deo efetuada", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} estĂĄ ligando para vocĂȘ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Reconectando
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} pessoa} other {{count,number} pessoas}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Chamada de voz", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Encerrar", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Sair", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Microfone desligado", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Microfone ligado", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Toque ligado", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Toque desligado", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ConfiguraçÔes", @@ -3468,13 +3668,25 @@ "messageformat": "Chamada em tela inteira", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Trocar para exibição em grade", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Alterar visualização", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Trocar para exibição individual", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Visualização em grade", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Visualização de barra lateral", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Visualização de quem estĂĄ falando", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Visualização atualizada", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Sair da chamada", @@ -3576,6 +3788,14 @@ "messageformat": "Ok", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "NĂŁo foi possĂ­vel editar a mensagem", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "SĂł Ă© possĂ­vel fazer {max,number} ediçÔes nesta mensagem.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Desculpe, esse link sgnl:// nĂŁo funcionou!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nome de usuĂĄrio", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Algo deu errado com seu nome de usuĂĄrio, pois ele nĂŁo estĂĄ mais atribuĂ­do Ă  sua conta.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Excluir nome de usuĂĄrio", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Criar nome de usuĂĄrio", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR code ou link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "O nome de usuĂĄrio precisa ser redefinido", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "O link do nome de usuĂĄrio precisa ser redefinido", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Compartilhe seu nome de usuĂĄrio", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Excluir nome de usuĂĄrio", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Essa ação excluirĂĄ o atual nome de usuĂĄrio do seu perfil, permitindo que outras pessoas cadastrem-se com esse nome de usuĂĄrio no perfil delas. Deseja prosseguir?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Esta ação vai remover seu nome de usuĂĄrio e desativar seu QR code e link. “{username}” ficarĂĄ disponĂ­vel para outros usuĂĄrios. Tem certeza?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "VocĂȘ nĂŁo poderĂĄ mais compartilhar ou ver stories. As atualizaçÔes de stories que vocĂȘ compartilhou recentemente tambĂ©m serĂŁo apagadas.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Idioma", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Idioma", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Idioma do sistema", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Pesquisar idiomas", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nenhum resultado encontrado para “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Definir", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Reinicie o Signal para aplicar", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Para mudar o idioma, Ă© necessĂĄrio reiniciar o app.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Reiniciar", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Atualização disponĂ­vel para a versĂŁo {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Ocorreu um erro ao salvar suas configuraçÔes. Por favor, tente novamente.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Enviar mensagem", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Mais estilos", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Redefinir", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Pronto", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Cor do link do nome de usuĂĄrio, {index,number} de {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Se vocĂȘ redefinir o QR code, o QR code e o link existentes vĂŁo parar de funcionar.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Redefinindo link
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR code e link nĂŁo definidos. Verifique sua conexĂŁo de rede e tente novamente.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Configure seu nome de usuĂĄrio do Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editado", + "messageformat": "Editado", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Enviar novamente", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Mais açÔes", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Chamadas", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nova chamada", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nova chamada", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Mais açÔes", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Limpar histĂłrico de chamadas", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Limpar histĂłrico de chamadas?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Esta ação excluirĂĄ permanentemente o histĂłrico de chamadas", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Limpar", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "HistĂłrico de Chamadas Apagado", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Clique para ver ou iniciar uma chamada", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Pesquisar", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrar por chamadas perdidas", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Alternar", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Sem chamadas recentes. Comece ligando para um amigo.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nenhum resultado encontrado para “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Recebida", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Realizada", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Perdida", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Chamada em grupo", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nenhuma conversa recente.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nenhum resultado encontrado para “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Chamada de voz efetuada} other {Recebendo chamada de voz}}} Video {{direction, select, Outgoing {Chamada de vĂ­deo efetuada} other {Chamada de vĂ­deo recebida}}} Group {{direction, select, Outgoing {Chamada de grupo efetuada} other {Recebendo chamada de grupo}}} other {{direction, select, Outgoing {Fazendo chamada} other {Recebendo chamada}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Chamada de voz perdida} Video {Chamada de vĂ­deo perdida} Group {Chamada de grupo perdida} other {Chamada perdida}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Chamada de voz nĂŁo atendida} Video {Chamada de vĂ­deo nĂŁo atendida} Group {Chamada em grupo nĂŁo atendida} other {Chamada nĂŁo atendida}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Chamada de voz recusada} Video {Chamada de vĂ­deo recusada} Group {Chamada em grupo recusada} other {Chamada recusada}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} outra pessoa estĂĄ digitando.} other {{count,number} outras pessoas estĂŁo digitando.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Novidades", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Pequenas alteraçÔes adicionais, correçÔes de bugs e melhorias de desempenho. Agradecemos por usar o Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Este update inclui algumas melhorias de chamadas de voz e de vĂ­deo, alĂ©m de algumas pequenas atualizaçÔes de documentos (valeu, {linkToGithub}!)" + "icu:WhatsNew__v6.39--0": { + "messageformat": "Agora vocĂȘ pode mudar o idioma do Signal sem alterar as configuraçÔes do seu sistema (ConfiguraçÔes do Signal > AparĂȘncia > Idioma)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Atualizamos alguns Ă­cones de notificaçÔes de grupos." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Corrigimos um atraso pequeno que Ă s vezes acontecia no macOS, apĂłs entrar no lobby de uma chamada." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Corrigimos a animação de transição para blocos de vĂ­deo quando alguĂ©m entra ou sai de uma chamada em grupo." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Agora vocĂȘ pode clicar em uma foto de perfil ou avatar de grupo no nome do chat para acessar rapidamente as configuraçÔes do chat ou ver stories nĂŁo visualizados da conversa. Valeu, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/pt-PT/messages.json b/_locales/pt-PT/messages.json index 7c2a5d6e21..5ae88dcef5 100644 --- a/_locales/pt-PT/messages.json +++ b/_locales/pt-PT/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Erro na base de dados", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ocorreu um erro na base de dados. Pode copiar o erro e entrar em contacto com o suporte do Signal para ajudar a corrigir o problema. Se precisar de usar o Signal imediatamente, pode apagar os seus dados e reiniciar.\n\nEntre em contacto com o suporte visitando: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Eliminar todos os dados e reiniciar", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Eliminar dados e reiniciar", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Eliminar permanentemente todos os dados?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Todo o seu histĂłrico de mensagens e suportes de dados serĂŁo eliminados permanentemente deste dispositivo. PoderĂĄ utilizar o Signal neste dispositivo depois de o voltar a vincular. Isto nĂŁo irĂĄ eliminar nenhuns dados do seu telemĂłvel.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "A versĂŁo da sua base de dados nĂŁo corresponde a esta versĂŁo do Signal. Certifique-se de que estĂĄ a abrir a versĂŁo mais recente do Signal no computador.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Ficheiro", @@ -300,6 +316,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Houve um problema com o seu nome de utilizador, o mesmo jĂĄ nĂŁo estĂĄ atribuĂ­do Ă  sua conta. Pode voltar a configurĂĄ-lo ou pode escolher um novo.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Resolver agora", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Houve um problema com o cĂłdigo QR e link do seu nome de utilizador, jĂĄ nĂŁo Ă© vĂĄlido. Crie um novo link para partilhar com outras pessoas.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Resolver agora", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Mostrar separadores", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ocultar separadores", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ocorreu um erro", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} nĂŁo lida(s)", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marcada como nĂŁo lida", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Chamadas", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "HistĂłrias", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "DefiniçÔes", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Atualizar o Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Perfil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Voltar", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Estes chats estĂŁo arquivados e aparecerĂŁo na caixa de entrada apenas caso receba novas mensagens.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Telefonar mesmo assim", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Aderir na mesma", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continuar chamada", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Os nĂșmeros de segurança estĂŁo a ser atualizados.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Saber mais", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "NĂșmero de segurança anterior", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "PrĂłximo nĂșmero de segurança", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "VersĂŁo do nĂșmero de segurança, {index,number} de {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marcar como verificado", @@ -663,33 +747,41 @@ "messageformat": "Limpar verificação", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Para verificar a criptografia de ponta a ponta com {name}, compare os nĂșmeros acima com os nĂșmeros no dispositivo dessa pessoa. TambĂ©m Ă© possĂ­vel escanear seu cĂłdigo com um dispositivo.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Saber mais", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Para verificar a a encriptação ponta-a-ponta com {name}, corresponda a carta de cor em cima com o seu dispositivo e compare os nĂșmeros. Se nĂŁo corresponder, use o outro par de nĂșmeros de segurança. SĂł um par precisa de corresponder.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Para verificar a criptografia de ponta a ponta com {name}, compare os nĂșmeros acima com os nĂșmeros no dispositivo dessa pessoa. TambĂ©m Ă© possĂ­vel escanear seu cĂłdigo com um dispositivo.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "AlteraçÔes aos NĂșmeros de Segurança", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Os nĂșmeros de segurança estĂŁo a ser atualizados ao longo de um perĂ­odo de transição para possibilitarem as opçÔes de privacidade do Signal a serem lançadas em breve.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Para verificar os nĂșmeros de segurança, corresponda a carta de cor com o dispositivo do seu contacto. Se nĂŁo corresponder, use o outro par de nĂșmeros de segurança. SĂł um par precisa de corresponder.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Necessita de ajuda?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Entendido", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "SerĂĄ criado um nĂșmero de segurança com esta pessoa depois de trocar mensagens com a mesma.", @@ -1267,10 +1359,6 @@ "messageformat": "Ver multimĂ©dia recente", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Se deseja verificar a segurança da sua encriptação ponto-a-ponto com {name}, compare os nĂșmeros acima com os nĂșmeros existentes no dispositivo dessa pessoa. TambĂ©m Ă© possĂ­vel fazer scan do cĂłdigo QR em cima.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Ainda nĂŁo trocou mensagens com este contacto. O seu nĂșmero de segurança estarĂĄ disponĂ­vel a partir da primeira mensagem." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Eliminar", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Eliminar mensagens", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Eliminar chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Eliminar mensagens?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Este chat serĂĄ eliminado deste dispositivo.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "As mensagens neste chat serĂŁo eliminadas deste dispositivo. Ainda pode procurar este chat apĂłs eliminar as mensagens.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Abandonar grupo", @@ -1438,6 +1526,14 @@ "messageformat": "O seu histĂłrico de mensagens para ambos os chats foi juntado aqui.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pertence a {conversationTitle}. Ambos sĂŁo membros de {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pertence a {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatura da imagem da mensagem", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ligar novamente", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Iniciar chamada", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Entrar na chamada", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Microfone silenciado devido ao tamanho da chamada", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "NotificaçÔes de chamada", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "A chamada encontra-se cheia", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "CĂąmara", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Entrar", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Iniciar", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Chamada cheia", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "CĂąmara desativada", @@ -1621,10 +1725,6 @@ "messageformat": "Ligar cĂąmara", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silenciar", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microfone desativado", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Desativar silĂȘncio micro", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Partilhar", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Apresentação desativada", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Parar apresentação", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Tocar", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupo demasiado grande para tocar todos os participantes.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Ativar o som de toque", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Desativar toque", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Ativar toque", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Mais opçÔes", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "VocĂȘ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "A sua cĂąmara encontra-se desligada", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Ver nĂșmero de segurança", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mensagem", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Ver nĂșmero de segurança", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Falha ao procurar o nĂșmero de telefone. Verifique a sua ligação e tente novamente.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "As ediçÔes sĂł podem ser aplicadas dentro de 3 horas a partir do momento em que enviou esta mensagem.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "As ediçÔes sĂł podem ser aplicadas dentro de 24 horas a partir do momento em que enviou esta mensagem.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Esta mensagem foi eliminada.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Anexo demasiado grande para exibir.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Alguns anexos sĂŁo demasiado grandes para exibir.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ImpossĂ­vel aceder aos detalhes da doação", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Apenas versĂŁo beta do Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "A edição de mensagens sĂł estĂĄ disponĂ­vel para utilizadores da versĂŁo beta Signal. Se editar uma mensagem, esta sĂł ficarĂĄ visĂ­vel para pessoas que estejam na versĂŁo beta do Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editar mensagem", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Se editar uma mensagem, esta sĂł ficarĂĄ visĂ­vel para pessoas que estejam na versĂŁo beta do Signal. Elas poderĂŁo ver que editou uma mensagem.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "A receber videochamada
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "A efetuar chamada de voz", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "A efetuar videochamada", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} estĂĄ a ligar-lhe", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "A ligar novamente
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} pessoa} other {{count,number} pessoas}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Chamada de ĂĄudio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Terminar", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Sair", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Microfone desligado", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Microfone ligado", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Toque ligado", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Toque desligado", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "DefiniçÔes", @@ -3468,13 +3668,25 @@ "messageformat": "chamada em ecrĂŁ completo", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Mudar para vista de grelha", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Alterar vista", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Mudar para vista de altifalante", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Vista em grelha", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Vista em barra lateral", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Vista do interlocutor", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Vista atualizada", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Abandonar chamada", @@ -3576,6 +3788,14 @@ "messageformat": "Ok", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "NĂŁo Ă© possĂ­vel editar a mensagem", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "SĂł {max,number} ediçÔes podem ser aplicadas a esta mensagem.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Desculpe, esse link sgnl:// nĂŁo faz sentido!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nome de utilizador", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Houve um problema com o seu nome de utilizador, o mesmo jĂĄ nĂŁo estĂĄ atribuĂ­do Ă  sua conta.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Eliminar nome de utilizador", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Criar nome de utilizador", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "CĂłdigo QR ou link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "O nome de utilizador requer reiniciar", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "O link do nome de utilizador requer reiniciar", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Partilhe o seu nome de utilizador", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Eliminar nome de utilizador", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Esta ação removerĂĄ o seu nome de utilizador, permitindo que outras pessoas se registem com esse nome de utilizador. Deseja prosseguir?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Isto irĂĄ remover o seu nome de utilizador e desativarĂĄ o seu cĂłdigo QR e link. “{username}” ficarĂĄ disponĂ­vel para ser utilizado por outros. Tem a certeza?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "JĂĄ nĂŁo poderĂĄ partilhar ou ver histĂłrias. As atualizaçÔes de histĂłrias que tenha partilhado recentemente tambĂ©m serĂŁo eliminadas.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Idioma", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Idioma", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Idioma de sistema", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Pesquisar idiomas", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nenhum resultado para “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Definir", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Reinicie o Signal para aplicar", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Para alterar o idioma, a app tem de reiniciar.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Reiniciar", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "EstĂĄ disponĂ­vel uma atualização para a versĂŁo {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Ocorreu um erro ao tentar guardar as suas definiçÔes. Por favor, tente novamente.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mensagem", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Mais estilos", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Reiniciar", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ConcluĂ­do", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Cor do link do nome de utilizador, {index,number} de {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Se redefinir o seu cĂłdigo QR, o seu cĂłdigo QR e link existentes deixarĂŁo de funcionar.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "A repor link
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "CĂłdigo QR e link nĂŁo definidos. Verifique a sua ligação Ă  internet e tente novamente.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Configure o seu nome de utilizador do Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editado", + "messageformat": "Editada", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Reenviar", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Mais açÔes", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Chamadas", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nova chamada", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nova chamada", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Mais açÔes", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Limpar histĂłrico de chamadas", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Limpar histĂłrico de chamadas?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Isto irĂĄ eliminar permanentemente todo o histĂłrico de chamadas", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Limpar", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "HistĂłrico de Chamadas Apagado", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Clique para ver ou iniciar uma chamada", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Procurar", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrar por perdidas", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Alternar", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Sem chamadas recentes. Comece por ligar a um amigo.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nenhum resultado para “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Entrada", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "SaĂ­da", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Perdida", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Chamada de grupo", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "NĂŁo hĂĄ conversas recentes.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nenhum resultado para “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {A efetuar chamada de voz} other {A receber chamada de voz}}} Video {{direction, select, Outgoing {A efetuar videochamada} other {A receber videochamada}}} Group {{direction, select, Outgoing {Chamada de grupo enviada} other {Chamada de grupo recebida}}} other {{direction, select, Outgoing {A efetuar chamada} other {A Receber Chamada}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Chamada de voz perdida} Video {Chamada de video perdida} Group {Chamada de grupo perdida} other {Chamada nĂŁo atendida}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Chamada de voz nĂŁo atendida} Video {Videochamada nĂŁo atendida} Group {Chamada de grupo nĂŁo atendida} other {Chamada nĂŁo atendida}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Chamada de voz rejeitada} Video {Videochamada rejeitada} Group {Chamada de grupo rejeitada} other {Chamada rejeitada}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} estĂĄ a escrever.} other {{count,number} estĂŁo a escrever.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Novidades", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Pequenos ajustes adicionais, correçÔes de bugs e melhorias de desempenho. Obrigado por usar o Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Esta atualização inclui algumas melhorias de chamadas de voz e de vĂ­deo, alĂ©m de algumas pequenas atualizaçÔes de documentos (obrigado, {linkToGithub}!)" + "icu:WhatsNew__v6.39--0": { + "messageformat": "Agora pode alterar o idioma selecionado no Signal sem alterar as definiçÔes do sistema (DefiniçÔes do Signal > AparĂȘncia > Idioma)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "AlterĂĄmos alguns Ă­cones das notificaçÔes de grupo." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Corrigimos um breve atraso que Ă s vezes ocorria ao entrar num lobby de chamadas em dispositivos macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Corrigimos a animação de transição para os mosaicos de vĂ­deo quando alguĂ©m entra ou sai de uma chamada em grupo." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Agora pode clicar numa foto de perfil ou avatar de grupo no cabeçalho do chat para aceder rapidamente Ă s definiçÔes de chat ou ver quaisquer histĂłrias nĂŁo vistas desse chat. Obrigado, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ro-RO/messages.json b/_locales/ro-RO/messages.json index 709b185f39..669bb628e8 100644 --- a/_locales/ro-RO/messages.json +++ b/_locales/ro-RO/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Eroare de bază de date", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "A apărut o eroare la baza de date. Poți copia eroarea și contacta serviciul de asistență Signal, pentru a ajuta la remedierea problemei. Dacă trebuie să utilizezi Signal imediat, ĂźÈ›i poți șterge datele și să repornești.\n\nContactează serviciul de asistență vizitĂąnd: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Șterge toate datele și repornește", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Șterge datele și repornește", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Ștergi toate datele permanent?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Tot istoricul mesajelor și conținutul media vor fi șterse definitiv de pe acest dispozitiv. Vei putea folosi Signal pe acest dispozitiv după ce Ăźl reconectezi. Asta nu va șterge datele de pe telefonul tău.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Versiunea bazei de date nu se potrivește cu această versiune de Signal. Asigură-te că deschizi cea mai nouă versiune de Signal pe computer.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Fișier", @@ -300,6 +316,70 @@ "messageformat": "Conversații", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Ceva nu a funcționat corect cu numele tău de utilizator, nu mai este atribuit contului tău. Poți Ăźncerca să Ăźl stabilești din nou sau să alegi unul nou.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Repară acum", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Ceva nu a funcționat cu codul tău QR și linkul numelui de utilizator, nu mai este valid. Creează un link nou pe care să Ăźl distribui altora.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Repară acum", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Arată file", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ascunde Filele", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "A apărut o eroare", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} necitite", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Marchează necitit", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Conversații", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Apeluri", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Povești", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Setări", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Actualizează Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Înapoi", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Aceste conversații sunt arhivate și vor fi vizibile Ăźn Inbox doar dacă sunt primite mesaje noi.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Sună oricum", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Alătură-te oricum", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continuă apelul", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Se actualizează numerele de siguranță.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Află mai multe", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Numărul de siguranță anterior", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Următorul număr de siguranță", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Versiunea numărului de siguranță, {index,number} din {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Marchează ca fiind verificat", @@ -663,33 +747,41 @@ "messageformat": "Șterge verificarea", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Pentru a verifica criptarea integrală cu {name}, compară numerele de mai sus cu cele de pe dispozitivul lor. Ei pot, de asemenea, să scaneze codul tău cu dispozitivul lor.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Află mai multe", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Pentru a verifica criptarea integrală a conversației tale cu {name}, potrivește cardul de culoare de mai sus cu dispozitivul său și compară numerele. Dacă nu se potrivesc, glisează și Ăźncearcă cealaltă pereche de numere de siguranță. Doar o pereche trebuie să se potrivească.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Pentru a verifica criptarea integrală cu {name}, compară numerele de mai sus cu cele de pe dispozitivul lor. Ei pot, de asemenea, să scaneze codul tău cu dispozitivul lor.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Modificări ale numerelor de siguranță", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Numerele de siguranță sunt actualizate Ăźntr-o perioadă de tranziție pentru a activa viitoarele funcții de confidențialitate Ăźn Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Pentru a verifica numerele de siguranță, potrivește cardul de culoare cu dispozitivul persoanei de contact. Dacă nu se potrivesc, Ăźncearcă cealaltă pereche de numere de siguranță. Doar o pereche trebuie să se potrivească.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Ai nevoie de ajutor?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Am Ăźnțeles", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Un număr de siguranță va fi creat cu această persoană după ce schimbi mesaje cu ea.", @@ -1267,10 +1359,6 @@ "messageformat": "Afișare media recente", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Pentru a verifica securitatea criptării integrale cu {name}, compară numerele de mai sus cu cele de pe dispozitivul lor. Ei pot, de asemenea, să scaneze codul qr de mai sus.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Nu ai schimbat pĂąnă acum nici un mesaj cu acest contact. Numărul de siguranță va fi disponibil după primul mesaj." }, @@ -1334,17 +1422,17 @@ "messageformat": "Informații", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Șterge", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Șterge mesajele", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Ștergi conversația?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Ștergi mesajele?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Această conversație va fi ștearsă de pe acest dispozitiv.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Mesajele din această conversație vor fi șterse de pe acest dispozitiv. Poți căuta Ăźn continuare acest chat, după ce ștergi mesajele.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Părăsește grupul", @@ -1438,6 +1526,14 @@ "messageformat": "Istoricul mesajelor pentru ambele conversații au fost cumulate aici.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} aparține lui {conversationTitle}. Sunteți membri ai {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} aparține persoanei {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatură a unei imagini dintr-un mesaj citat", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Sună din nou", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Începe apelul", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Alătură-te apelului", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Microfonul a fost oprit datorită dimensiuni apelului", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Notificări de apel", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Numărul maxim de participanți a fost atins", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Cameră foto", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Alătură-te", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Start", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Numărul maxim de participanți a fost atins", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Cameră dezactivată", @@ -1621,10 +1725,6 @@ "messageformat": "Pornește camera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Silențios", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microfon dezactivat", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Pornește microfonul", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Partajează", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Prezentări dezactivate", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Oprește prezentarea", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Sună", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupul este prea mare pentru a apela participanții.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Activează soneria", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Dezactivează soneria", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Activează soneria", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Mai multe opțiuni", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Tu", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Camera ta este oprită", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Afișează Numărul de Siguranță", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mesaj", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Afișează Numărul de Siguranță", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Nu s-a găsit numărul de telefon. Verifică conexiunea și Ăźncearcă din nou.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Modificările pot fi aplicate numai Ăźn termen de 3 de ore din momentul Ăźn care ai trimis acest mesaj.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Editările pot fi făcute numai Ăźn termen de 24 de ore de la trimiterea acestui mesaj.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Acest mesaj a fost șters.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Atașamentul este prea mare pentru a fi afișat.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Unele atașamente sunt prea mari pentru a fi afișate.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nu am putut să obținem detaliile donației", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Doar Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Editarea mesajelor este disponibilă numai pentru utilizatorii Signal beta. Dacă editezi un mesaj, acesta va fi vizibil numai pentru persoanele care au cea mai recentă versiune de Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Editează Mesajul", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Dacă editezi un mesaj, acesta va fi vizibil numai pentru persoanele care au cea mai recentă versiune de Signal beta. Ei vor putea să vadă că ai editat un mesaj.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Apel de intrare video...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Apel de ieșire vocal", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Apel de ieșire video", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} te apelează", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Se reconectează
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} persoană} few {{count,number} persoane} other {{count,number} persoane}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Apel audio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "SfĂąrßit", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Părăsește", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Microfon dezactivat", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Microfon activat", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Sunet de apel activat", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Sunet de apel dezactivat", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Setări", @@ -3468,13 +3668,25 @@ "messageformat": "Apel pe ecran complet", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Comută la vizualizare grilă", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Schimbă vizualizarea", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Comută la vizualizare vorbitor", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Vizualizare grilă", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Vizualizare bara laterală", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Vizualizare vorbitor", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Vizualizare actualizată", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Părăsește apelul", @@ -3576,6 +3788,14 @@ "messageformat": "Okay", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Nu se poate edita mesajul", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Numai {max,number} modificări pot fi aplicate acestui mesaj.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Ne pare rău, linkul sgnl:// nu a fost Ăźnțeles!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Nume de utilizator", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Ceva nu a funcționat corect cu numele tău de utilizator, nu mai este atribuit contului tău.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Șterge numele de utilizator", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Creați un nume de utilizator", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Cod QR sau link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Numele de utilizator trebuie resetat", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Linkul numelui de utilizator trebuie resetat", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Împărtășește-ți numele de utilizator", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Șterge numele de utilizator", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Această acțiune va elimina numele tău de utilizator, permiÈ›Ăąnd altor utilizatori să Ăźl revendice. Ești sigur?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Aceasta ĂźÈ›i va elimina numele de utilizator și va dezactiva codul QR și linkul. „ {username}” va fi disponibil pentru a fi revendicat de alții. Ești sigur?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Nu vei mai putea să distribui sau să vezi povești. Actualizările poveștilor pe care le-ai distribuit recent vor fi și ele șterse.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Limba", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Limba", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Limbă sistem", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Caută limbi", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Fără rezultate pentru „{searchTerm}“", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Aplicare", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Repornește Signal pentru a aplica", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Pentru a schimba limba, aplicația trebuie să repornească.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Repornește", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Este disponibilă actualizarea la versiunea {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "S-a produs o eroare la salvarea setărilor tale. Te rugăm să Ăźncerci din nou.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mesaj", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Mai multe stiluri", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Resetare", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Gata", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Culoarea linkului numelui de utilizator, {index,number} din {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Dacă resetezi codul QR, codul QR existent și linkul nu vor mai funcționa.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Se resetează linkul...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Codul QR și linkul nu sunt setate. Verifică-ți conexiunea la rețea și Ăźncearcă din nou.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Stabilește-ți numele de utilizator Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "editat", + "messageformat": "Editat", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Trimite din Nou", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Mai multe acțiuni", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Apeluri", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Apel nou", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Apel nou", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Mai multe acțiuni", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Ștergeți istoricul apelurilor", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Ștergi istoricul apelurilor?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Aceasta va șterge definitiv tot istoricul apelurilor", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Eliminare", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Istoria apelurilor a fost ștearsă", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Dă clic și vezi sau Ăźncepe un apel", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Caută", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrează după apeluri ratate", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Comutare", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nu exista apeluri recente. Începe prin a suna un prieten.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Fără rezultate pentru „{query}“", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Primite", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Trimise", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Ratate", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Apel de grup", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Fără conversații recente.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Fără rezultate pentru „{query}“", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Apel de ieșire vocal} other {Apel de intrare vocal}}} Video {{direction, select, Outgoing {Apel de ieșire video} other {Apel de intrare video}}} Group {{direction, select, Outgoing {Apel de ieșire de grup} other {Apel de intrare de grup}}} other {{direction, select, Outgoing {Apel de ieșire} other {Apel de intrare}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Apel vocal nepreluat} Video {Apel video nepreluat} Group {Apel de grup ratat} other {Apel ratat}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Apel vocal nepreluat} Video {Apel video nepreluat} Group {Apel de grup fără răspuns} other {Apel fără răspuns}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Apel video respins} Video {Apel video respins} Group {Apel de grup respins} other {Respinge apelul}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {Ăźncă {count,number} scrie.} few {Ăźncă {count,number} alții scriu.} other {Ăźncă {count,number} alții scriu.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Ce este nou", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Mici ajustări, soluționări de bug-uri și Ăźmbunătățiri ale performanței. Mersi că folosești Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Această actualizare include cĂąteva Ăźmbunătățiri pentru apelurile vocale și video și cĂąteva actualizări minore ale documentației (mulțumesc, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Acum poți schimba limba selectată Ăźn Signal fără a modifica setările sistemului (Setări semnal > Aspect > Limbă)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Am modificat pictogramele de notificare care apar pentru actualizările grupului, cum ar fi atunci cĂąnd cineva nou se alătură unui grup. Aceste pictograme ajută la Ăźmbunătățirea lizibilității, mai ales dacă locuiești Ăźn Ăźntunericul temei Ăźntunecate. Pictogramele anterioare doar Ăźncercau să facă față. Noile pictograme sunt 100% pricepute la Ăźntuneric." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Am remediat o scurtă ĂźntĂąrziere care avea loc uneori Ăźn zona de așteptare a participării la un apel, pe dispozitive macOS, ceea ce ar trebui să nu-ți mai lase loc de nicio scuză atunci cĂąnd ai ĂźntĂąrziat o jumătate de secundă la ĂźntĂąlnire." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Am remediat animația de tranziție, atunci cĂąnd cineva se alătură sau părăsește un apel de grup. CĂąnd apare pe ecran fața unui prieten, acest lucru indică activitate pe rețeaua de socializare." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Acum poți da clic pe o poză de profil sau pe un avatar de grup din antetul chatului pentru a accesa rapid setările de chat sau pentru a vedea orice povești nevăzute din acel chat. Mulțumesc, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index 577a63ae7d..e0b7384f27 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ĐžŃˆĐžĐ±Đșа базы ĐŽĐ°ĐœĐœŃ‹Ń…", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ĐŸŃ€ĐŸĐžĐ·ĐŸŃˆĐ»Đ° ĐŸŃˆĐžĐ±Đșа базы ĐŽĐ°ĐœĐœŃ‹Ń…. Вы ĐŒĐŸĐ¶Đ”Ń‚Đ” ŃĐŸĐ·ĐŽĐ°Ń‚ŃŒ ĐșĐŸĐżĐžŃŽ ĐŸŃˆĐžĐ±ĐșĐž Đž ĐŸĐ±Ń€Đ°Ń‚ĐžŃ‚ŃŒŃŃ ĐČ ŃĐ»ŃƒĐ¶Đ±Ńƒ ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐșĐž Signal ĐŽĐ»Ń Ń€Đ”ŃˆĐ”ĐœĐžŃ ĐżŃ€ĐŸĐ±Đ»Đ”ĐŒŃ‹. ЕслО ĐČы Ń…ĐŸŃ‚ĐžŃ‚Đ” ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать Signal ĐœĐ”ĐŒĐ”ĐŽĐ»Đ”ĐœĐœĐŸ, ĐČы ĐŒĐŸĐ¶Đ”Ń‚Đ” ŃƒĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐŽĐ°ĐœĐœŃ‹Đ” Đž ĐżĐ”Ń€Đ”Đ·Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒŃŃ.\n\nĐĄĐČŃĐ·Đ°Ń‚ŃŒŃŃ с ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐșĐŸĐč ĐŒĐŸĐ¶ĐœĐŸ ĐżĐŸ Đ°ĐŽŃ€Đ”ŃŃƒ: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐČсД ĐŽĐ°ĐœĐœŃ‹Đ” Đž ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚ŃŒ", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐŽĐ°ĐœĐœŃ‹Đ” Đž ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚ŃŒ", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐČсД ĐŽĐ°ĐœĐœŃ‹Đ” бДзĐČĐŸĐ·ĐČŃ€Đ°Ń‚ĐœĐŸ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Вся ĐžŃŃ‚ĐŸŃ€ĐžŃ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐč Đž ĐŒĐ”ĐŽĐžĐ°Ń„Đ°Đčлы Đ±ŃƒĐŽŃƒŃ‚ бДзĐČĐŸĐ·ĐČŃ€Đ°Ń‚ĐœĐŸ ŃƒĐŽĐ°Đ»Đ”ĐœŃ‹ с ŃŃ‚ĐŸĐłĐŸ ŃƒŃŃ‚Ń€ĐŸĐčстĐČа. Вы ŃĐŒĐŸĐ¶Đ”Ń‚Đ” ĐżĐŸĐ»ŃŒĐ·ĐŸĐČаться Signal ĐœĐ° ŃŃ‚ĐŸĐŒ ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐ” ĐżĐŸŃĐ»Đ” ĐżĐ”Ń€Đ”ĐżĐŸĐŽĐșĐ»ŃŽŃ‡Đ”ĐœĐžŃ. Đ­Ń‚ĐŸ ĐœĐ” проĐČДЎДт Đș ŃƒĐŽĐ°Đ»Đ”ĐœĐžŃŽ ĐŽĐ°ĐœĐœŃ‹Ń… Оз ĐČĐ°ŃˆĐ”ĐłĐŸ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ°.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Ваша ĐČĐ”Ń€ŃĐžŃ базы ĐŽĐ°ĐœĐœŃ‹Ń… ĐœĐ” ŃĐŸĐŸŃ‚ĐČДтстĐČŃƒĐ”Ń‚ ŃŃ‚ĐŸĐč ĐČДрсОО Signal. ĐŁĐ±Đ”ĐŽĐžŃ‚Đ”ŃŃŒ, Ń‡Ń‚ĐŸ ĐœĐ° ĐČĐ°ŃˆĐ”ĐŒ ĐșĐŸĐŒĐżŃŒŃŽŃ‚Đ”Ń€Đ” ŃƒŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐ° ŃĐ°ĐŒĐ°Ń ĐżĐŸŃĐ»Đ”ĐŽĐœŃŃ ĐČĐ”Ń€ŃĐžŃ Signal.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ЀаĐčĐ»", @@ -300,6 +316,70 @@ "messageformat": "Чаты", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Đ§Ń‚ĐŸ-Ń‚ĐŸ ĐżĐŸŃˆĐ»ĐŸ ĐœĐ” таĐș с ĐČĐ°ŃˆĐžĐŒ ĐžĐŒĐ”ĐœĐ”ĐŒ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń, ĐŸĐœĐŸ Đ±ĐŸĐ»ŃŒŃˆĐ” ĐœĐ” заĐșŃ€Đ”ĐżĐ»Đ”ĐœĐŸ за ĐČашДĐč ŃƒŃ‡Ń‘Ń‚ĐœĐŸĐč Đ·Đ°ĐżĐžŃŃŒŃŽ. Вы ĐŒĐŸĐ¶Đ”Ń‚Đ” ĐżĐŸĐżŃ€ĐŸĐ±ĐŸĐČать ŃƒŃŃ‚Đ°ĐœĐŸĐČоть Đ”ĐłĐŸ ŃĐœĐŸĐČа ОлО ĐČŃ‹Đ±Ń€Đ°Ń‚ŃŒ ĐœĐŸĐČĐŸĐ”.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ИспраĐČоть сДĐčчас", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Đ§Ń‚ĐŸ-Ń‚ĐŸ ĐżĐŸŃˆĐ»ĐŸ ĐœĐ” таĐș с QR-ĐșĐŸĐŽĐŸĐŒ Đž ссылĐșĐŸĐč ĐœĐ° ĐČашД ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń, ĐŸĐœĐž Đ±ĐŸĐ»ŃŒŃˆĐ” ĐœĐ” ĐŽĐ”ĐčстĐČĐžŃ‚Đ”Đ»ŃŒĐœŃ‹. ĐĄĐŸĐ·ĐŽĐ°ĐčтД ĐœĐŸĐČую ссылĐșу, Ń‡Ń‚ĐŸĐ±Ń‹ ĐŽĐ”Đ»ĐžŃ‚ŃŒŃŃ Đ”Đč с ĐŽŃ€ŃƒĐłĐžĐŒĐž.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ИспраĐČоть сДĐčчас", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ĐŸĐŸĐșĐ°Đ·Đ°Ń‚ŃŒ ĐČĐșлаЎĐșĐž", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ĐĄĐșрыть ĐČĐșлаЎĐșĐž", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ĐŸŃ€ĐŸĐžĐ·ĐŸŃˆĐ»Đ° ĐŸŃˆĐžĐ±Đșа", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "ĐĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐœŃ‹Ń…: {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ĐžŃ‚ĐŒĐ”Ń‡Đ”ĐœŃ‹ ĐșаĐș ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐœŃ‹Đ”", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Чаты", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ЗĐČĐŸĐœĐșĐž", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžĐž", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ĐžĐ±ĐœĐŸĐČоть Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„ĐžĐ»ŃŒ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ĐĐ°Đ·Đ°ĐŽ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Это чаты архоĐČĐžŃ€ĐŸĐČĐ°ĐœŃ‹ Đž ĐżĐŸŃĐČятся ĐČĐŸ Â«Đ’Ń…ĐŸĐŽŃŃ‰ĐžŃ…Â», Ń‚ĐŸĐ»ŃŒĐșĐŸ ДслО Đ±ŃƒĐŽŃƒŃ‚ ĐżĐŸĐ»ŃƒŃ‡Đ”ĐœŃ‹ ĐœĐŸĐČыД ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Всё раĐČĐœĐŸ ĐżĐŸĐ·ĐČĐŸĐœĐžŃ‚ŃŒ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Всё раĐČĐœĐŸ ĐŸŃ‚ĐżŃ€Đ°ĐČоть", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ĐŸŃ€ĐŸĐŽĐŸĐ»Đ¶ĐžŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ĐšĐŸĐŽŃ‹ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž ĐŸĐ±ĐœĐŸĐČĐ»ŃŃŽŃ‚ŃŃ.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ĐŁĐ·ĐœĐ°Ń‚ŃŒ Đ±ĐŸĐ»ŃŒŃˆĐ”", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐŸŃ€Đ”ĐŽŃ‹ĐŽŃƒŃ‰ĐžĐč ĐșĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ĐĐŸĐČыĐč ĐșĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Đ’Đ”Ń€ŃĐžŃ ĐșĐŸĐŽĐ° Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž: {index,number} Оз {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ĐžŃ‚ĐŒĐ”Ń‚ĐžŃ‚ŃŒ ĐșаĐș ĐżĐŸĐŽŃ‚ĐČĐ”Ń€Đ¶ĐŽŃ‘ĐœĐœŃ‹Đč", @@ -663,33 +747,41 @@ "messageformat": "ĐĄĐ±Ń€ĐŸŃĐžŃ‚ŃŒ ĐżĐŸĐŽŃ‚ĐČĐ”Ń€Đ¶ĐŽĐ”ĐœĐžĐ”", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Đ§Ń‚ĐŸĐ±Ń‹ ĐżĐŸĐŽŃ‚ĐČĐ”Ń€ĐŽĐžŃ‚ŃŒ ĐČашД сĐșĐČĐŸĐ·ĐœĐŸĐ” ŃˆĐžŃ„Ń€ĐŸĐČĐ°ĐœĐžĐ” с {name}, сраĐČĐœĐžŃ‚Đ” цофры, уĐșĐ°Đ·Đ°ĐœĐœŃ‹Đ” ĐČŃ‹ŃˆĐ”, с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸĐŒ ŃĐŸĐ±Đ”ŃĐ”ĐŽĐœĐžĐșа. ĐžĐœ таĐșжД ĐŒĐŸĐ¶Đ”Ń‚ ĐŸŃ‚ŃĐșĐ°ĐœĐžŃ€ĐŸĐČать ĐșĐŸĐŽ ĐœĐ° ĐČĐ°ŃˆĐ”ĐŒ ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐ”.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ĐŁĐ·ĐœĐ°Ń‚ŃŒ Đ±ĐŸĐ»ŃŒŃˆĐ”", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Đ§Ń‚ĐŸĐ±Ń‹ ŃƒĐŽĐŸŃŃ‚ĐŸĐČĐ”Ń€ĐžŃ‚ŃŒŃŃ ĐČ ĐœĐ°Đ»ĐžŃ‡ĐžĐž сĐșĐČĐŸĐ·ĐœĐŸĐłĐŸ ŃˆĐžŃ„Ń€ĐŸĐČĐ°ĐœĐžŃ с {name}, ŃĐŸĐżĐŸŃŃ‚Đ°ĐČŃŒŃ‚Đ” цĐČĐ”Ń‚ĐœŃƒŃŽ ĐșĐ°Ń€Ń‚ĐŸŃ‡Đșу ĐČŃ‹ŃˆĐ” с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸĐŒ ĐČĐ°ŃˆĐ”ĐłĐŸ ŃĐŸĐ±Đ”ŃĐ”ĐŽĐœĐžĐșа Đž сраĐČĐœĐžŃ‚Đ” цофры. ЕслО ĐŸĐœĐž ĐœĐ” ŃĐŸĐČпаЮают, ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД Юругую пару ĐșĐŸĐŽĐŸĐČ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž. КаĐș ĐŒĐžĐœĐžĐŒŃƒĐŒ ĐŸĐŽĐœĐ° пара ĐșĐŸĐŽĐŸĐČ ĐŽĐŸĐ»Đ¶ĐœĐ° ŃĐŸĐČпаЮать.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Đ§Ń‚ĐŸĐ±Ń‹ ĐżĐŸĐŽŃ‚ĐČĐ”Ń€ĐŽĐžŃ‚ŃŒ ĐČашД сĐșĐČĐŸĐ·ĐœĐŸĐ” ŃˆĐžŃ„Ń€ĐŸĐČĐ°ĐœĐžĐ” с {name}, сраĐČĐœĐžŃ‚Đ” цофры, уĐșĐ°Đ·Đ°ĐœĐœŃ‹Đ” ĐČŃ‹ŃˆĐ”, с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸĐŒ ŃĐŸĐ±Đ”ŃĐ”ĐŽĐœĐžĐșа. ĐžĐœ таĐșжД ĐŒĐŸĐ¶Đ”Ń‚ ĐŸŃ‚ŃĐșĐ°ĐœĐžŃ€ĐŸĐČать ĐșĐŸĐŽ ĐœĐ° ĐČĐ°ŃˆĐ”ĐŒ ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐ”.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ”ĐœĐžŃ ĐČ ĐșĐŸĐŽĐ°Ń… Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ĐšĐŸĐŽŃ‹ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž ĐŸĐ±ĐœĐŸĐČĐ»ŃŃŽŃ‚ŃŃ ĐČ Ń‚Đ”Ń‡Đ”ĐœĐžĐ” ĐżĐ”Ń€Đ”Ń…ĐŸĐŽĐœĐŸĐłĐŸ ĐżĐ”Ń€ĐžĐŸĐŽĐ° ĐŽĐ»Ń ĐČĐșĐ»ŃŽŃ‡Đ”ĐœĐžŃ ĐœĐŸĐČых Ń„ŃƒĐœĐșцоĐč ĐșĐŸĐœŃ„ĐžĐŽĐ”ĐœŃ†ĐžĐ°Đ»ŃŒĐœĐŸŃŃ‚Đž ĐČ Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Đ§Ń‚ĐŸĐ±Ń‹ ĐżŃ€ĐŸĐČĐ”Ń€ĐžŃ‚ŃŒ ĐșĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž, сраĐČĐœĐžŃ‚Đ” цĐČĐ”Ń‚ĐœŃƒŃŽ ĐșĐ°Ń€Ń‚ĐŸŃ‡Đșу с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸĐŒ ĐČĐ°ŃˆĐ”ĐłĐŸ ŃĐŸĐ±Đ”ŃĐ”ĐŽĐœĐžĐșа. ЕслО цофры ĐœĐ° ĐœĐžŃ… ĐœĐ” ŃĐŸĐČпаЮают, ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД Юругую пару ĐșĐŸĐŽĐŸĐČ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž. КаĐș ĐŒĐžĐœĐžĐŒŃƒĐŒ ĐŸĐŽĐœĐ° пара ĐșĐŸĐŽĐŸĐČ ĐŽĐŸĐ»Đ¶ĐœĐ° ŃĐŸĐČпаЮать.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ĐŃƒĐ¶ĐœĐ° ĐżĐŸĐŒĐŸŃ‰ŃŒ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ĐŸĐŸĐœŃŃ‚ĐœĐŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ĐšĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž Đ±ŃƒĐŽĐ”Ń‚ ŃĐŸĐ·ĐŽĐ°Đœ ĐżĐŸŃĐ»Đ” ĐŸĐ±ĐŒĐ”ĐœĐ° ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃĐŒĐž с ŃŃ‚ĐžĐŒ Ń‡Đ”Đ»ĐŸĐČĐ”ĐșĐŸĐŒ.", @@ -1267,10 +1359,6 @@ "messageformat": "ĐŸŃ€ĐŸŃĐŒĐŸŃ‚Ń€Đ”Ń‚ŃŒ ĐœĐ”ĐŽĐ°ĐČĐœĐžĐ” ĐŒĐ”ĐŽĐžĐ°", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Đ§Ń‚ĐŸĐ±Ń‹ ĐżĐŸĐŽŃ‚ĐČĐ”Ń€ĐŽĐžŃ‚ŃŒ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚ŃŒ ĐČĐ°ŃˆĐ”ĐłĐŸ сĐșĐČĐŸĐ·ĐœĐŸĐłĐŸ ŃˆĐžŃ„Ń€ĐŸĐČĐ°ĐœĐžŃ с {name}, сраĐČĐœĐžŃ‚Đ” цофры, уĐșĐ°Đ·Đ°ĐœĐœŃ‹Đ” ĐČŃ‹ŃˆĐ”, с ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸĐŒ ŃĐŸĐ±Đ”ŃĐ”ĐŽĐœĐžĐșа. ĐžĐœ таĐșжД ĐŒĐŸĐ¶Đ”Ń‚ ĐŸŃ‚ŃĐșĐ°ĐœĐžŃ€ĐŸĐČать QR-ĐșĐŸĐŽ, уĐșĐ°Đ·Đ°ĐœĐœŃ‹Đč ĐČŃ‹ŃˆĐ”.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Вы ДщД ĐœĐ” ĐŸĐ±ĐŒĐ”ĐœŃĐ»ĐžŃŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃĐŒĐž с ĐŽĐ°ĐœĐœŃ‹ĐŒ ĐșĐŸĐœŃ‚Đ°ĐșŃ‚ĐŸĐŒ. ĐšĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž ŃŃ‚Đ°ĐœĐ”Ń‚ ĐŽĐŸŃŃ‚ŃƒĐżĐ”Đœ ĐżĐŸŃĐ»Đ” ĐŸŃ‚ĐżŃ€Đ°ĐČĐșĐž пДрĐČĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ." }, @@ -1334,17 +1422,17 @@ "messageformat": "Đ˜ĐœŃ„ĐŸŃ€ĐŒĐ°Ń†ĐžŃ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ чат?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Đ­Ń‚ĐŸŃ‚ чат Đ±ŃƒĐŽĐ”Ń‚ ŃƒĐŽĐ°Đ»Ń‘Đœ с ŃŃ‚ĐŸĐłĐŸ ŃƒŃŃ‚Ń€ĐŸĐčстĐČа.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ĐĄĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ ĐČ ŃŃ‚ĐŸĐŒ чатД Đ±ŃƒĐŽŃƒŃ‚ ŃƒĐŽĐ°Đ»Đ”ĐœŃ‹ с ŃŃ‚ĐŸĐłĐŸ ŃƒŃŃ‚Ń€ĐŸĐčстĐČа. ĐŸĐŸŃĐ»Đ” ŃƒĐŽĐ°Đ»Đ”ĐœĐžŃ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐč ĐČы ŃĐŒĐŸĐ¶Đ”Ń‚Đ” ĐżŃ€ĐŸĐŽĐŸĐ»Đ¶Đ°Ń‚ŃŒ ĐżĐŸĐžŃĐș ĐżĐŸ ŃŃ‚ĐŸĐŒŃƒ чату.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ĐŸĐŸĐșĐžĐœŃƒŃ‚ŃŒ группу", @@ -1438,6 +1526,14 @@ "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃ ĐČашох ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐč ĐŽĐ»Ń ĐŸĐ±ĐŸĐžŃ… Ń‡Đ°Ń‚ĐŸĐČ Đ±Ń‹Đ»Đ° ĐŸĐ±ŃŠĐ”ĐŽĐžĐœĐ”ĐœĐ° Đ·ĐŽĐ”ŃŃŒ.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} ĐżŃ€ĐžĐœĐ°ĐŽĐ»Đ”Đ¶ĐžŃ‚ {conversationTitle}. Вы ĐŸĐ±Đ° яĐČĐ»ŃĐ”Ń‚Đ”ŃŃŒ ŃƒŃ‡Đ°ŃŃ‚ĐœĐžĐșĐ°ĐŒĐž {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} ĐżŃ€ĐžĐœĐ°ĐŽĐ»Đ”Đ¶ĐžŃ‚ {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ĐœĐžĐœĐžĐ°Ń‚ŃŽŃ€Đ° ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ Оз Ń†ĐžŃ‚ĐžŃ€ŃƒĐ”ĐŒĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ĐŸĐŸĐ·ĐČĐŸĐœĐžŃ‚ŃŒ ŃĐœĐŸĐČа", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Начать Đ·ĐČĐŸĐœĐŸĐș", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ĐŸŃ€ĐžŃĐŸĐ”ĐŽĐžĐœĐžŃ‚ŃŒŃŃ Đș Đ·ĐČĐŸĐœĐșу", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ был ĐŸŃ‚ĐșĐ»ŃŽŃ‡Ń‘Đœ Оз-за ĐșĐŸĐ»ĐžŃ‡Đ”ŃŃ‚ĐČа ŃƒŃ‡Đ°ŃŃ‚ĐœĐžĐșĐŸĐČ Đ·ĐČĐŸĐœĐșа", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ĐŁĐČĐ”ĐŽĐŸĐŒĐ»Đ”ĐœĐžŃ ĐŸ Đ·ĐČĐŸĐœĐșах", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ЗĐČĐŸĐœĐŸĐș Đ·Đ°ĐżĐŸĐ»ĐœĐ”Đœ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Đ’ĐŸĐčто", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ĐĐ°Ń‡Đ°Đ»ĐŸ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ЗĐČĐŸĐœĐŸĐș Đ·Đ°ĐżĐŸĐ»ĐœĐ”Đœ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ° ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”ĐœĐ°", @@ -1621,10 +1725,6 @@ "messageformat": "ВĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒ ĐșĐ°ĐŒĐ”Ń€Ńƒ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ОтĐșĐ». Đ·ĐČуĐș", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”Đœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ВĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒ ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ĐŸĐŸĐŽĐ”Đ»ĐžŃ‚ŃŒŃŃ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ĐŸĐŸĐșаз ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”Đœ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ĐžŃŃ‚Đ°ĐœĐŸĐČоть ĐżĐŸĐșаз", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ЗĐČĐŸĐœĐžŃ‚ŃŒ", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ĐĐ”ĐČĐŸĐ·ĐŒĐŸĐ¶ĐœĐŸ Đ·ĐČĐŸĐœĐžŃ‚ŃŒ ŃƒŃ‡Đ°ŃŃ‚ĐœĐžĐșĐ°ĐŒ: группа слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐ°Ń.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ВĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ВыĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ВĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Đ‘ĐŸĐ»ŃŒŃˆĐ” ĐŸĐżŃ†ĐžĐč", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Вы", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Ваша ĐșĐ°ĐŒĐ”Ń€Đ° ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”ĐœĐ°", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ĐŸĐŸŃĐŒĐŸŃ‚Ń€Đ”Ń‚ŃŒ ĐșĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ĐĄĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ĐŸĐŸŃĐŒĐŸŃ‚Ń€Đ”Ń‚ŃŒ ĐșĐŸĐŽ Đ±Đ”Đ·ĐŸĐżĐ°ŃĐœĐŸŃŃ‚Đž", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ĐČŃ‹ĐżĐŸĐ»ĐœĐžŃ‚ŃŒ Đ·Đ°ĐżŃ€ĐŸŃ ĐżĐŸ ĐœĐŸĐŒĐ”Ń€Ńƒ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ°. ĐŸŃ€ĐŸĐČĐ”Ń€ŃŒŃ‚Đ” ĐČашД ĐżĐŸĐŽĐșĐ»ŃŽŃ‡Đ”ĐœĐžĐ” Đș ĐžĐœŃ‚Đ”Ń€ĐœĐ”Ń‚Ńƒ Đž ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД Дщё раз.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ”ĐœĐžŃ ĐŒĐŸĐłŃƒŃ‚ Đ±Ń‹Ń‚ŃŒ ĐČĐœĐ”ŃĐ”ĐœŃ‹ Ń‚ĐŸĐ»ŃŒĐșĐŸ ĐČ Ń‚Đ”Ń‡Đ”ĐœĐžĐ” '{'0'}' часа(-ĐŸĐČ) с ĐŒĐŸĐŒĐ”ĐœŃ‚Đ° ĐŸŃ‚ĐżŃ€Đ°ĐČĐșĐž ŃŃ‚ĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ”ĐœĐžŃ ĐŒĐŸĐłŃƒŃ‚ Đ±Ń‹Ń‚ŃŒ ĐČĐœĐ”ŃĐ”ĐœŃ‹ Ń‚ĐŸĐ»ŃŒĐșĐŸ ĐČ Ń‚Đ”Ń‡Đ”ĐœĐžĐ” 24 Ń‡Đ°ŃĐŸĐČ Ń ĐŒĐŸĐŒĐ”ĐœŃ‚Đ° ĐŸŃ‚ĐżŃ€Đ°ĐČĐșĐž ŃŃ‚ĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Đ­Ń‚ĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ” Đ±Ń‹Đ»ĐŸ ŃƒĐŽĐ°Đ»Đ”ĐœĐŸ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Đ’Đ»ĐŸĐ¶Đ”ĐœĐžĐ” слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐŸĐ” ĐŽĐ»Ń ĐŸŃ‚ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ĐĐ”ĐșĐŸŃ‚ĐŸŃ€Ń‹Đ” ĐČĐ»ĐŸĐ¶Đ”ĐœĐžŃ слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐžĐ” ĐŽĐ»Ń ĐŸŃ‚ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ĐĐ”ĐČĐŸĐ·ĐŒĐŸĐ¶ĐœĐŸ ĐżĐŸĐ»ŃƒŃ‡ĐžŃ‚ŃŒ ĐŽĐ°ĐœĐœŃ‹Đ” ĐŸ ĐżĐŸĐ¶Đ”Ń€Ń‚ĐČĐŸĐČĐ°ĐœĐžĐž", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ĐąĐŸĐ»ŃŒĐșĐŸ ĐŽĐ»Ń бДта-ĐČДрсОО Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "РДЎаĐșŃ‚ĐžŃ€ĐŸĐČĐ°ĐœĐžĐ” ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐč ĐŽĐŸŃŃ‚ŃƒĐżĐœĐŸ Ń‚ĐŸĐ»ŃŒĐșĐŸ ĐŽĐ»Ń ĐżĐŸĐ»ŃŒĐ·ĐŸĐČатДлДĐč бДта-ĐČДрсОО Signal. ЕслО ĐČы ĐŸŃ‚Ń€Đ”ĐŽĐ°ĐșŃ‚ĐžŃ€ŃƒĐ”Ń‚Đ” ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”, ŃŃ‚ĐŸ уĐČоЮят Ń‚ĐŸĐ»ŃŒĐșĐŸ тД, ĐșŃ‚ĐŸ ĐżĐŸĐ»ŃŒĐ·ŃƒĐ”Ń‚ŃŃ ĐżĐŸŃĐ»Đ”ĐŽĐœĐ”Đč бДта-ĐČДрсОДĐč Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "РДЎаĐșŃ‚ĐžŃ€ĐŸĐČать ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ЕслО ĐČы ĐŸŃ‚Ń€Đ”ĐŽĐ°ĐșŃ‚ĐžŃ€ŃƒĐ”Ń‚Đ” ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”, ŃŃ‚ĐŸ уĐČоЮят Ń‚ĐŸĐ»ŃŒĐșĐŸ тД, ĐșŃ‚ĐŸ ĐżĐŸĐ»ŃŒĐ·ŃƒĐ”Ń‚ŃŃ ĐżĐŸŃĐ»Đ”ĐŽĐœĐžĐŒĐž ĐČĐ”Ń€ŃĐžŃĐŒĐž Signal. ĐžĐœĐž уĐČоЮят, Ń‡Ń‚ĐŸ ĐČы ĐŸŃ‚Ń€Đ”ĐŽĐ°ĐșŃ‚ĐžŃ€ĐŸĐČалО ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Đ’Ń…ĐŸĐŽŃŃ‰ĐžĐč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} Đ·ĐČĐŸĐœĐžŃ‚ ĐČĐ°ĐŒ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ĐŸĐ”Ń€Đ”ĐżĐŸĐŽĐșĐ»ŃŽŃ‡Đ°Đ”ĐŒŃŃâ€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} Ń‡Đ”Đ»ĐŸĐČĐ”Đșа} few {{count,number} Ń‡Đ”Đ»ĐŸĐČĐ”Đș} many {{count,number} люЎДĐč} other {{count,number} люЎДĐč}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ĐŃƒĐŽĐžĐŸĐ·ĐČĐŸĐœĐŸĐș", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ОĐșĐŸĐœŃ‡Đ°ĐœĐžĐ”", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ĐŸĐŸĐșĐžĐœŃƒŃ‚ŃŒ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ ĐČыĐșĐ»ŃŽŃ‡Đ”Đœ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ ĐČĐșĐ»ŃŽŃ‡Ń‘Đœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ЗĐČĐŸĐœĐșĐž ĐČĐșĐ»ŃŽŃ‡Đ”ĐœŃ‹", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ЗĐČĐŸĐœĐșĐž ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”ĐœŃ‹", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž", @@ -3468,13 +3668,25 @@ "messageformat": "РазĐČĐ”Ń€ĐœŃƒŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒŃŃ ĐœĐ° ĐČОЎ сДтĐșĐž", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚ŃŒ ĐČОЎ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒŃŃ ĐœĐ° ĐČОЎ ĐłĐŸĐČĐŸŃ€ŃŃ‰Đ”ĐłĐŸ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ВоЮ: сДтĐșа", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ВоЮ: Đ±ĐŸĐșĐŸĐČая ĐżĐ°ĐœĐ”Đ»ŃŒ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ВоЮ: ĐłĐŸĐČĐŸŃ€ŃŃ‰ĐžĐč", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ВоЮ ĐŸĐ±ĐœĐŸĐČĐ»Ń‘Đœ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ĐŸĐŸĐșĐžĐœŃƒŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", @@ -3576,6 +3788,14 @@ "messageformat": "Đ„ĐŸŃ€ĐŸŃˆĐŸ", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ĐĐ”ĐČĐŸĐ·ĐŒĐŸĐ¶ĐœĐŸ ĐžĐ·ĐŒĐ”ĐœĐžŃ‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ĐąĐŸĐ»ŃŒĐșĐŸ {max,number} ĐžĐ·ĐŒĐ”ĐœĐ”ĐœĐžĐč ĐŒĐŸĐłŃƒŃ‚ Đ±Ń‹Ń‚ŃŒ ĐČĐœĐ”ŃĐ”ĐœŃ‹ ĐČ ŃŃ‚ĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ИзĐČĐžĐœĐžŃ‚Đ”, эта ссылĐșа sgnl:// ĐČ ĐŽĐ°ĐœĐœŃ‹Đč ĐŒĐŸĐŒĐ”ĐœŃ‚ ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČĐ°Đ”Ń‚ŃŃ Signal Desktop.", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Đ˜ĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Đ§Ń‚ĐŸ-Ń‚ĐŸ ĐżĐŸŃˆĐ»ĐŸ ĐœĐ” таĐș с ĐČĐ°ŃˆĐžĐŒ ĐžĐŒĐ”ĐœĐ”ĐŒ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń, ĐŸĐœĐŸ Đ±ĐŸĐ»ŃŒŃˆĐ” ĐœĐ” заĐșŃ€Đ”ĐżĐ»Đ”ĐœĐŸ за ĐČашДĐč ŃƒŃ‡Ń‘Ń‚ĐœĐŸĐč Đ·Đ°ĐżĐžŃŃŒŃŽ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ĐĄĐŸĐ·ĐŽĐ°Ń‚ŃŒ ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-ĐșĐŸĐŽ ОлО ссылĐșа", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Đ˜ĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń ĐœĐ”ĐŸĐ±Ń…ĐŸĐŽĐžĐŒĐŸ ŃĐ±Ń€ĐŸŃĐžŃ‚ŃŒ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ХсылĐșу ĐœĐ° ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń ĐœĐ”ĐŸĐ±Ń…ĐŸĐŽĐžĐŒĐŸ ŃĐ±Ń€ĐŸŃĐžŃ‚ŃŒ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ĐŸĐŸĐŽĐ”Đ»ĐžŃ‚Đ”ŃŃŒ ĐČĐ°ŃˆĐžĐŒ ĐžĐŒĐ”ĐœĐ”ĐŒ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Đ­Ń‚ĐŸ ĐŽĐ”ĐčстĐČОД ŃƒĐŽĐ°Đ»ĐžŃ‚ ĐČашД ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń, Đž ĐŽŃ€ŃƒĐłĐžĐ” ĐżĐŸĐ»ŃŒĐ·ĐŸĐČатДлО ŃĐŒĐŸĐłŃƒŃ‚ Đ”ĐłĐŸ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать. Вы уĐČĐ”Ń€Đ”ĐœŃ‹?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Đ­Ń‚ĐŸ проĐČДЎДт Đș ŃƒĐŽĐ°Đ»Đ”ĐœĐžŃŽ ĐžĐŒĐ”ĐœĐž ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń Đž ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”ĐœĐžŃŽ QR-ĐșĐŸĐŽĐ° Đž ссылĐșĐž. Đ˜ĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń «{username}» Đ±ŃƒĐŽĐ”Ń‚ ĐŽĐŸŃŃ‚ŃƒĐżĐœĐŸ ĐŽĐ»Ń Юругох жДлающОх. Вы уĐČĐ”Ń€Đ”ĐœŃ‹?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Вы Đ±ĐŸĐ»ŃŒŃˆĐ” ĐœĐ” ŃĐŒĐŸĐ¶Đ”Ń‚Đ” ĐŽĐ”Đ»ĐžŃ‚ŃŒŃŃ ĐžŃŃ‚ĐŸŃ€ĐžŃĐŒĐž ОлО ĐżŃ€ĐŸŃĐŒĐ°Ń‚Ń€ĐžĐČать ох. ВсД ĐžŃŃ‚ĐŸŃ€ĐžĐž, ĐșĐŸŃ‚ĐŸŃ€Ń‹ĐŒĐž ĐČы ĐœĐ”ĐŽĐ°ĐČĐœĐŸ ĐżĐŸĐŽĐ”Đ»ĐžĐ»ĐžŃŃŒ, Đ±ŃƒĐŽŃƒŃ‚ таĐșжД ŃƒĐŽĐ°Đ»Đ”ĐœŃ‹.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ĐŻĐ·Ń‹Đș (Language)", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ĐŻĐ·Ń‹Đș (Language)", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ĐŻĐ·Ń‹Đș ŃĐžŃŃ‚Đ”ĐŒŃ‹", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ИсĐșать ŃĐ·Ń‹Đș", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ĐĐ”Ń‚ Ń€Đ”Đ·ŃƒĐ»ŃŒŃ‚Đ°Ń‚ĐŸĐČ ĐŽĐ»Ń «{searchTerm}»", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ĐŁŃŃ‚Đ°ĐœĐŸĐČоть", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ĐŸĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚ŃŒ Signal ĐŽĐ»Ń ĐżŃ€ĐžĐŒĐ”ĐœĐ”ĐœĐžŃ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Đ”Đ»Ń ŃĐŒĐ”ĐœŃ‹ ŃĐ·Ń‹Đșа ĐœĐ”ĐŸĐ±Ń…ĐŸĐŽĐžĐŒĐŸ ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚ŃŒ ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐ”.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ĐŸĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚ŃŒ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Đ”ĐŸŃŃ‚ŃƒĐżĐœĐŸ ĐŸĐ±ĐœĐŸĐČĐ»Đ”ĐœĐžĐ” ĐŽĐŸ ĐČДрсОО {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ĐŸŃ€ĐŸĐžĐ·ĐŸŃˆĐ»Đ° ĐŸŃˆĐžĐ±Đșа про ŃĐŸŃ…Ń€Đ°ĐœĐ”ĐœĐžĐž ĐČашох ĐœĐ°ŃŃ‚Ń€ĐŸĐ”Đș. ĐŸĐŸĐ¶Đ°Đ»ŃƒĐčста, ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД ДщД раз.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ĐĄĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐ”", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Đ”Ń€ŃƒĐłĐžĐ” стОлО", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ĐĄĐ±Ń€ĐŸŃĐžŃ‚ŃŒ", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Đ“ĐŸŃ‚ĐŸĐČĐŸ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ĐŠĐČДт ссылĐșĐž ĐœĐ° ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń, {index,number} Оз {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Про ŃĐ±Ń€ĐŸŃĐ” QR-ĐșĐŸĐŽĐ° ĐČаш ŃŃƒŃ‰Đ”ŃŃ‚ĐČующоĐč QR-ĐșĐŸĐŽ Đž ссылĐșа ĐżĐ”Ń€Đ”ŃŃ‚Đ°ĐœŃƒŃ‚ Ń€Đ°Đ±ĐŸŃ‚Đ°Ń‚ŃŒ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ĐĄĐ±Ń€ĐŸŃ ссылĐșĐž...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-ĐșĐŸĐŽ Đž ссылĐșа ĐœĐ” ŃƒŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœŃ‹. ĐŸŃ€ĐŸĐČĐ”Ń€ŃŒŃ‚Đ” ĐČашД ĐżĐŸĐŽĐșĐ»ŃŽŃ‡Đ”ĐœĐžĐ” Đș ĐžĐœŃ‚Đ”Ń€ĐœĐ”Ń‚Ńƒ Đž ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД Дщё раз.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ĐĐ°ŃŃ‚Ń€ĐŸĐčтД сĐČĐŸŃ‘ ĐžĐŒŃ ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "ĐžĐ·ĐŒĐ”ĐœĐ”ĐœĐŸ", + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ”ĐœĐŸ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ОтпраĐČоть ДщД раз", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Đ‘ĐŸĐ»ŃŒŃˆĐ” ĐŽĐ”ĐčстĐČĐžĐč", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ЗĐČĐŸĐœĐșĐž", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ĐĐŸĐČыĐč Đ·ĐČĐŸĐœĐŸĐș", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ĐĐŸĐČыĐč Đ·ĐČĐŸĐœĐŸĐș", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Đ‘ĐŸĐ»ŃŒŃˆĐ” ĐŽĐ”ĐčстĐČĐžĐč", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Очостоть ĐžŃŃ‚ĐŸŃ€ĐžŃŽ Đ·ĐČĐŸĐœĐșĐŸĐČ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Очостоть ĐžŃŃ‚ĐŸŃ€ĐžŃŽ Đ·ĐČĐŸĐœĐșĐŸĐČ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Вся ĐžŃŃ‚ĐŸŃ€ĐžŃ Đ·ĐČĐŸĐœĐșĐŸĐČ Đ±ŃƒĐŽĐ”Ń‚ бДзĐČĐŸĐ·ĐČŃ€Đ°Ń‚ĐœĐŸ ŃƒĐŽĐ°Đ»Đ”ĐœĐ°", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃ Đ·ĐČĐŸĐœĐșĐŸĐČ ŃŃ‚Ń‘Ń€Ń‚Đ°", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ĐĐ°Đ¶ĐŒĐžŃ‚Đ”, Ń‡Ń‚ĐŸĐ±Ń‹ ĐżŃ€ĐŸŃĐŒĐŸŃ‚Ń€Đ”Ń‚ŃŒ ОлО ĐœĐ°Ń‡Đ°Ń‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ĐŸĐŸĐžŃĐș", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ĐžŃ‚Ń„ĐžĐ»ŃŒŃ‚Ń€ĐŸĐČать ĐżĐŸ ĐżŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐœŃ‹ĐŒ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĐĐ”Ń‚ ĐœĐ”ĐŽĐ°ĐČĐœĐžŃ… Đ·ĐČĐŸĐœĐșĐŸĐČ. ĐĐ°Ń‡ĐœĐžŃ‚Đ” ŃĐŸ Đ·ĐČĐŸĐœĐșа Юругу.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ĐĐ”Ń‚ Ń€Đ”Đ·ŃƒĐ»ŃŒŃ‚Đ°Ń‚ĐŸĐČ ĐŽĐ»Ń «{query}»", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Đ’Ń…ĐŸĐŽŃŃ‰ĐžĐ”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐ”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐœŃ‹Đ”", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Đ“Ń€ŃƒĐżĐżĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĐĐ”Ń‚ ĐżĐŸŃĐ»Đ”ĐŽĐœĐžŃ… Ń€Đ°Đ·ĐłĐŸĐČĐŸŃ€ĐŸĐČ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ĐĐ”Ń‚ Ń€Đ”Đ·ŃƒĐ»ŃŒŃ‚Đ°Ń‚ĐŸĐČ ĐŽĐ»Ń «{query}»", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș}}} Video {{direction, select, Outgoing {Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐžĐč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș}}} Group {{direction, select, Outgoing {Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐč ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐžĐč ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș}}} other {{direction, select, Outgoing {Đ˜ŃŃ…ĐŸĐŽŃŃ‰ĐžĐč Đ·ĐČĐŸĐœĐŸĐș} other {Đ’Ń…ĐŸĐŽŃŃ‰ĐžĐč ĐČŃ‹Đ·ĐŸĐČ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐœŃ‹Đč ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} Video {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐœŃ‹Đč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș} Group {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐœŃ‹Đč ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} other {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐœŃ‹Đč Đ·ĐČĐŸĐœĐŸĐș}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ĐĐ”ĐŸŃ‚ĐČĐ”Ń‡Đ”ĐœĐœŃ‹Đč ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} Video {ĐĐ”ĐŸŃ‚ĐČĐ”Ń‡Đ”ĐœĐœŃ‹Đč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș} Group {ĐĐ”ĐŸŃ‚ĐČĐ”Ń‡Đ”ĐœĐœŃ‹Đč ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} other {ĐĐ”ĐŸŃ‚ĐČĐ”Ń‡Đ”ĐœĐœŃ‹Đč Đ·ĐČĐŸĐœĐŸĐș}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ОтĐșĐ»ĐŸĐœŃ‘ĐœĐœŃ‹Đč Đ°ŃƒĐŽĐžĐŸĐ·ĐČĐŸĐœĐŸĐș} Video {ОтĐșĐ»ĐŸĐœŃ‘ĐœĐœŃ‹Đč ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐŸĐș} Group {ОтĐșĐ»ĐŸĐœŃ‘ĐœĐœŃ‹Đč ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐč Đ·ĐČĐŸĐœĐŸĐș} other {ОтĐșĐ»ĐŸĐœĐžŃ‚ŃŒ Đ·ĐČĐŸĐœĐŸĐș}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {Ещё {count,number} пДчатаДт.} few {Ещё {count,number} пДчатают.} many {Ещё {count,number} пДчатают.} other {Ещё {count,number} пДчатают.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Đ§Ń‚ĐŸ ĐœĐŸĐČĐŸĐłĐŸ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "ĐĐ”Đ±ĐŸĐ»ŃŒŃˆĐžĐ” ĐžĐ·ĐŒĐ”ĐœĐ”ĐœĐžŃ, оспраĐČĐ»Đ”ĐœĐžŃ ĐŸŃˆĐžĐ±ĐŸĐș Đž ŃƒĐ»ŃƒŃ‡ŃˆĐ”ĐœĐžŃ ĐżŃ€ĐŸĐžĐ·ĐČĐŸĐŽĐžŃ‚Đ”Đ»ŃŒĐœĐŸŃŃ‚Đž. ĐĄĐżĐ°ŃĐžĐ±ĐŸ за Ń‚ĐŸ, Ń‡Ń‚ĐŸ ĐżĐŸĐ»ŃŒĐ·ŃƒĐ”Ń‚Đ”ŃŃŒ Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Đ”Đ°ĐœĐœĐŸĐ” ĐŸĐ±ĐœĐŸĐČĐ»Đ”ĐœĐžĐ” ĐČĐșлючаДт ĐČ ŃĐ”Đ±Ń ряЮ ŃƒĐ»ŃƒŃ‡ŃˆĐ”ĐœĐžĐč ĐŽĐ»Ń Đ°ŃƒĐŽĐžĐŸ- Đž ĐČĐžĐŽĐ”ĐŸĐ·ĐČĐŸĐœĐșĐŸĐČ, а таĐșжД ĐœĐ”Đ±ĐŸĐ»ŃŒŃˆĐžĐ” ĐŸĐ±ĐœĐŸĐČĐ»Đ”ĐœĐžŃ ĐŽĐŸĐșŃƒĐŒĐ”ĐœŃ‚Đ°Ń†ĐžĐž (ŃĐżĐ°ŃĐžĐ±ĐŸ, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "ĐąĐ”ĐżĐ”Ń€ŃŒ ĐŒĐŸĐ¶ĐœĐŸ ĐžĐ·ĐŒĐ”ĐœĐžŃ‚ŃŒ ĐČŃ‹Đ±Ń€Đ°ĐœĐœŃ‹Đč ŃĐ·Ń‹Đș ĐČ Signal бДз ĐžĐ·ĐŒĐ”ĐœĐ”ĐœĐžŃ ŃĐžŃŃ‚Đ”ĐŒĐœŃ‹Ń… ĐœĐ°ŃŃ‚Ń€ĐŸĐ”Đș (ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž Signal > ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž ĐžĐœŃ‚Đ”Ń€Ń„Đ”Đčса > ĐŻĐ·Ń‹Đș)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Мы ĐŸĐ±ĐœĐŸĐČОлО ĐœĐ”ĐșĐŸŃ‚ĐŸŃ€Ń‹Đ” Đ·ĐœĐ°Ń‡ĐșĐž уĐČĐ”ĐŽĐŸĐŒĐ»Đ”ĐœĐžĐč ĐČ ĐłŃ€ŃƒĐżĐżĐ°Ń…." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Мы ŃƒŃŃ‚Ń€Đ°ĐœĐžĐ»Đž ĐœĐ”Đ±ĐŸĐ»ŃŒŃˆŃƒŃŽ заЎДржĐșу, ĐșĐŸŃ‚ĐŸŃ€Đ°Ń ĐžĐœĐŸĐłĐŽĐ° ĐČĐŸĐ·ĐœĐžĐșала про ĐżĐŸĐŽĐșĐ»ŃŽŃ‡Đ”ĐœĐžĐž Đș Đ»ĐŸĐ±Đ±Đž Đ·ĐČĐŸĐœĐșа ĐœĐ° ŃƒŃŃ‚Ń€ĐŸĐčстĐČах с macOS. Đ˜ŃŃ‡Đ”Đ·Đ»Đ° ĐșаĐș ĐŒĐžĐœĐžĐŒŃƒĐŒ ĐŸĐŽĐœĐ° ĐżŃ€ĐžŃ‡ĐžĐœĐ° ĐŽĐ»Ń сДĐșŃƒĐœĐŽĐœĐŸĐłĐŸ ĐŸĐżĐŸĐ·ĐŽĐ°ĐœĐžŃ ĐœĐ° ŃĐŸĐČĐ”Ń‰Đ°ĐœĐžĐ”." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Мы оспраĐČОлО Đ°ĐœĐžĐŒĐ°Ń†ĐžŃŽ ĐżĐ”Ń€Đ”Ń…ĐŸĐŽĐ° ĐŽĐ»Ń ĐżĐ»ĐžŃ‚ĐŸĐș с ĐČĐžĐŽĐ”ĐŸ, ĐșĐŸĐłĐŽĐ° ĐșŃ‚ĐŸ-Ń‚ĐŸ ĐżŃ€ĐžŃĐŸĐ”ĐŽĐžĐœŃĐ”Ń‚ŃŃ Đș ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐŒŃƒ Đ·ĐČĐŸĐœĐșу ОлО ĐżĐŸĐșОЎаДт Đ”ĐłĐŸ. ĐąĐ”ĐżĐ”Ń€ŃŒ, ĐșĐŸĐłĐŽĐ° Đ»ĐžŃ†ĐŸ Юруга ĐżĐŸŃĐČĐ»ŃĐ”Ń‚ŃŃ ĐœĐ° эĐșŃ€Đ°ĐœĐ” ĐČĐŸ ĐČŃ€Đ”ĐŒŃ ĐłŃ€ŃƒĐżĐżĐŸĐČĐŸĐłĐŸ Đ·ĐČĐŸĐœĐșа, ĐČы Đ·ĐœĐ°Đ”Ń‚Đ”, ĐșаĐș ĐČŃ‹ĐłĐ»ŃĐŽĐžŃ‚ ĐœĐ°ŃŃ‚ĐŸŃŃ‰Đ°Ń ŃĐŸŃ†ĐžĐ°Đ»ŃŒĐœĐ°Ń аĐșтоĐČĐœĐŸŃŃ‚ŃŒ." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ĐąĐ”ĐżĐ”Ń€ŃŒ ĐČы ĐŒĐŸĐ¶Đ”Ń‚Đ” ĐœĐ°Đ¶Đ°Ń‚ŃŒ ĐœĐ° Ń„ĐŸŃ‚ĐŸ ĐżŃ€ĐŸŃ„ĐžĐ»Ń ОлО аĐČатар группы ĐČ Đ·Đ°ĐłĐŸĐ»ĐŸĐČĐșĐ” чата, Ń‡Ń‚ĐŸĐ±Ń‹ Đ±Ń‹ŃŃ‚Ń€ĐŸ ĐżĐŸĐ»ŃƒŃ‡ĐžŃ‚ŃŒ ĐŽĐŸŃŃ‚ŃƒĐż Đș ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșĐ°ĐŒ чата ОлО уĐČĐžĐŽĐ”Ń‚ŃŒ ĐČсД ĐœĐ”ĐżŃ€ĐŸŃĐŒĐŸŃ‚Ń€Đ”ĐœĐœŃ‹Đ” ĐžŃŃ‚ĐŸŃ€ĐžĐž Оз ĐœĐ”ĐłĐŸ. ĐĄĐżĐ°ŃĐžĐ±ĐŸ, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/sk-SK/messages.json b/_locales/sk-SK/messages.json index a47f3fddd6..551f056421 100644 --- a/_locales/sk-SK/messages.json +++ b/_locales/sk-SK/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Chyba databĂĄzy", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Vyskytla sa chyba databĂĄzy. MĂŽĆŸete skopĂ­rovaĆ„ chybu a kontaktovaĆ„ podporu Signal, aby vĂĄm pomohla problĂ©m vyrieĆĄiĆ„. Ak potrebujete Signal pouĆŸiĆ„ hneď teraz, mĂŽĆŸete vymazaĆ„ svoje Ășdaje a reĆĄtartovaĆ„ aplikĂĄciu.\n\nKontaktujte podporu na: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "VymazaĆ„ vĆĄetky dĂĄta a reĆĄtartovaĆ„", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "VymazaĆ„ Ășdaje a reĆĄtartovaĆ„", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Chcete natrvalo odstrĂĄniĆ„ vĆĄetky Ășdaje?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "CelĂĄ histĂłria sprĂĄv a vĆĄetky mĂ©diĂĄ budĂș natrvalo odstrĂĄnenĂ© z tohto zariadenia. Po opĂ€tovnom prepojenĂ­ budete mĂŽcĆ„ Signal znovu pouĆŸĂ­vaĆ„ na tomto zariadenĂ­. TĂœmto sa nevymaĆŸĂș ĆŸiadne Ășdaje z vĂĄĆĄho telefĂłnu.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Verzia vaĆĄej databĂĄzy sa nezhoduje s touto verziou Signalu. Uistite sa, ĆŸe na počítači otvĂĄrate najnovĆĄiu verziu aplikĂĄcie Signal.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&SĂșbor", @@ -300,6 +316,70 @@ "messageformat": "Čety", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Vyskytol sa problĂ©m s vaĆĄĂ­m pouĆŸĂ­vateÄŸskĂœm menom. UĆŸ nie je priradenĂ© k vĂĄĆĄmu Ășčtu. MĂŽĆŸete si ho skĂșsiĆ„ nastaviĆ„ znova alebo si vybraĆ„ novĂ©.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "OpraviĆ„ teraz", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Vyskytol sa problĂ©m s vaĆĄim QR kĂłdom a odkazom na pouĆŸĂ­vateÄŸskĂ© meno, uĆŸ nie sĂș platnĂ©. Vytvorte novĂœ odkaz a zdieÄŸajte ho s ostatnĂœmi.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "OpraviĆ„ teraz", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ZobraziĆ„ karty", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "SkryĆ„ karty", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Vyskytla sa chyba", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "NeprečítanĂ©: {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "OznačenĂ© ako neprečítanĂ©", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Čety", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Volania", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "PrĂ­behy", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Nastavenia", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "AktualizovaĆ„ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "SpÀƄ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Tieto čety sĂș archivovanĂ© a v schrĂĄnke prijatĂœch sprĂĄv sa zobrazia iba vtedy, ak dostanete novĂ© sprĂĄvy.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Aj tak zavolaĆ„", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Aj tak sa pripojiĆ„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "PokračovaĆ„ v hovore", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "BezpečnostnĂ© čísla sa aktualizujĂș.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ZistiĆ„ viac", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "PredchĂĄdzajĂșce bezpečnostnĂ© číslo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ĎalĆĄie bezpečnostnĂ© číslo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Verzia bezpečnostnĂ©ho čísla, {index,number} z {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "OznačiĆ„ ako overenĂ©", @@ -663,33 +747,41 @@ "messageformat": "ZruĆĄiĆ„ overenie", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Ak chcete overiĆ„ end-to-end ĆĄifrovanie s pouĆŸĂ­vateÄŸom {name}, porovnajte vyĆĄĆĄie uvedenĂ© čísla s ich zariadenĂ­m. MĂŽĆŸu tieĆŸ naskenovaĆ„ vĂĄĆĄ kĂłd pomocou svojho zariadenia.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ZistiĆ„ viac", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Ak chcete overiĆ„ end-to-end ĆĄifrovanie s pouĆŸĂ­vateÄŸom {name}, priraďte farebnĂș kartu vyĆĄĆĄie k ich zariadeniu a porovnajte zobrazenĂ© čísla. Ak sa tieto čísla nezhodujĂș, skĂșste ďalĆĄĂ­ pĂĄr bezpečnostnĂœch čísel. MusĂ­ sa zhodovaĆ„ iba jeden pĂĄr.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Ak chcete overiĆ„ end-to-end ĆĄifrovanie s pouĆŸĂ­vateÄŸom {name}, porovnajte vyĆĄĆĄie uvedenĂ© čísla s ich zariadenĂ­m. MĂŽĆŸu tieĆŸ naskenovaĆ„ vĂĄĆĄ kĂłd pomocou svojho zariadenia.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Zmeny v bezpečnostnĂœch číslach", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "AktualizĂĄcia bezpečnostnĂœch čísel bude prebiehaĆ„ počas prechodnej fĂĄzy, čo umoĆŸnĂ­ zavedenie novĂœch funkciĂ­ sĂșkromia pre Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Ak chcete overiĆ„ bezpečnostnĂ© čísla, porovnajte farebnĂș kartu so zariadenĂ­m vĂĄĆĄho kontaktu. Ak sa tieto čísla nezhodujĂș, skĂșste ďalĆĄĂ­ pĂĄr bezpečnostnĂœch čísel. MusĂ­ sa zhodovaĆ„ iba jeden pĂĄr.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Potrebujete pomĂŽcĆ„?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Rozumiem", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Po vĂœmene sprĂĄv s touto osobou sa vytvorĂ­ bezpečnostnĂ© číslo.", @@ -1267,10 +1359,6 @@ "messageformat": "ZobraziĆ„ nedĂĄvne mĂ©diĂĄ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Ak chcete overiĆ„ bezpečnosĆ„ svojho end-to-end ĆĄifrovania s pouĆŸĂ­vateÄŸom {name}, porovnajte vyĆĄĆĄie uvedenĂ© čísla s ich zariadenĂ­m. MĂŽĆŸu tieĆŸ naskenovaĆ„ vyĆĄĆĄie uvedenĂœ QR kĂłd.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "S tĂœmto kontaktom ste si eĆĄte nevymenili ĆŸiadne sprĂĄvy. BezpečnostnĂ© číslo bude dostupnĂ© po doručenĂ­ prvej sprĂĄvy." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "VymazaĆ„", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "VymazaĆ„ sprĂĄvy", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "VymazaĆ„ čet?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "VymazaĆ„ sprĂĄvy?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Tento čet sa vymaĆŸe z tohto zariadenia.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "SprĂĄvy v tomto čete budĂș vymazanĂ© z tohto zariadenia. Po vymazanĂ­ sprĂĄv budete mĂŽcĆ„ tento čet stĂĄle vyhÄŸadaĆ„.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "OpustiĆ„ skupinu", @@ -1438,6 +1526,14 @@ "messageformat": "HistĂłria sprĂĄv pre oba čety bola zlĂșčenĂĄ tu.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} patrĂ­ pouĆŸĂ­vateÄŸovi {conversationTitle}. Obaja ste členmi skupiny {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} patrĂ­ pouĆŸĂ­vateÄŸovi {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "NĂĄhÄŸad obrĂĄzku z citovanej sprĂĄvy.", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ZavolaĆ„ znovu", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ZačaĆ„ hovor", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "PripojiĆ„ sa k hovoru", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "MikrofĂłn je stlmenĂœ kvĂŽli veÄŸkosti hovoru", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Upozornenia na hovory", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Hovor je plne obsadenĂœ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "FotoaparĂĄt", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "PridaĆ„ sa", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ZačaĆ„", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Hovor je plne obsadenĂœ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera vypnutĂĄ", @@ -1621,10 +1725,6 @@ "messageformat": "ZapnĂșĆ„ kameru", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "StlmiĆ„", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "MikrofĂłn vypnutĂœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ZapnĂșĆ„ mikrofĂłn", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ZdieÄŸaĆ„", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "PrezentĂĄcia je zakĂĄzanĂĄ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "PrestaĆ„ prezentovaĆ„", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ZvoniĆ„", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Skupina je prĂ­liĆĄ veÄŸkĂĄ na to, aby vyzvåƈala ĂșčastnĂ­kom.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "PovoliĆ„ zvonenie", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "VypnĂșĆ„ zvonenie", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ZapnĂșĆ„ zvonenie", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Viac moĆŸnostĂ­", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Vy", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "VĂĄĆĄ fotoaparĂĄt je vypnutĂœ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ZobraziĆ„ bezpečnostnĂ© číslo", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "SprĂĄva", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ZobraziĆ„ bezpečnostnĂ© číslo", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Nepodarilo sa načítaĆ„ telefĂłnne číslo. Skontrolujte pripojenie a skĂșste to znova.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Úpravy je moĆŸnĂ© vykonaĆ„ len do 3 hodĂ­n od odoslania tejto sprĂĄvy.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Úpravy je moĆŸnĂ© vykonaĆ„ len do 24 hodĂ­n od odoslania tejto sprĂĄvy.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "TĂĄto sprĂĄva bola odstrĂĄnenĂĄ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "PrĂ­loha je prĂ­liĆĄ veÄŸkĂĄ, nie je moĆŸnĂ© ju zobraziĆ„.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "NiektorĂ© prĂ­lohy sĂș prĂ­liĆĄ veÄŸkĂ©, nie je moĆŸnĂ© ich zobraziĆ„.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Nepodarilo sa zĂ­skaĆ„ podrobnosti prĂ­spevku", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Len Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Úprava sprĂĄv je k dispozĂ­cii iba pre pouĆŸĂ­vateÄŸov beta verzie Signalu. Ak upravĂ­te sprĂĄvu, zobrazĂ­ sa iba ÄŸuďom, ktorĂ­ pouĆŸĂ­vajĂș najnovĆĄiu beta verziu Signalu.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "UpraviĆ„ sprĂĄvu", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Ak upravĂ­te sprĂĄvu, zobrazĂ­ sa iba ÄŸuďom, ktorĂ­ pouĆŸĂ­vajĂș najnovĆĄie verzie Signalu. Uvidia, ĆŸe ste upravili sprĂĄvu.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "PrichĂĄdzajĂșci videohovor
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "OdchĂĄdzajĂșci hlasovĂœ hovor", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "OdchĂĄdzajĂșci videohovor", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} vĂĄm volĂĄ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "PripĂĄja sa
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} osoba} few {{count,number} ÄŸudia} many {{count,number} ÄŸudĂ­} other {{count,number} ÄŸudĂ­}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio hovor", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "UkončiĆ„", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "OpustiĆ„", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "MikrofĂłn vypnutĂœ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "MikrofĂłn zapnutĂœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zvonenie zapnutĂ©", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zvonenie vypnutĂ©", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Nastavenia", @@ -3468,13 +3668,25 @@ "messageformat": "Hovor na celĂș obrazovku", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "PrepnĂșĆ„ na zobrazenie v mrieĆŸke", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ZmeniĆ„ zobrazenie", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "PrepnĂșĆ„ na zobrazenie rečnĂ­ka", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "MrieĆŸka", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "BočnĂœ panel", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "PrĂĄve hovoriaci", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Zobrazenie aktualizovanĂ©", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "OpustiĆ„ hovor", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "SprĂĄvu nie je moĆŸnĂ© upraviĆ„", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Na tĂșto sprĂĄvu je moĆŸnĂ© pouĆŸiĆ„ iba {max,number} Ășprav.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Prepáčte, ten odkaz sgnl:// nedĂĄval zmysel!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "PouĆŸĂ­vateÄŸskĂ© meno", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Vyskytol sa problĂ©m s vaĆĄĂ­m pouĆŸĂ­vateÄŸskĂœm menom. UĆŸ nie je priradenĂ© k vĂĄĆĄmu Ășčtu.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "OdstrĂĄniĆ„ pouĆŸĂ­vateÄŸskĂ© meno", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "VytvoriĆ„ pouĆŸĂ­vateÄŸskĂ© meno", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR kĂłd alebo odkaz", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "PouĆŸĂ­vateÄŸskĂ© meno je potrebnĂ© resetovaĆ„", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Odkaz na pouĆŸĂ­vateÄŸskĂ© meno je potrebnĂ© resetovaĆ„", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ZdieÄŸajte svoje pouĆŸĂ­vateÄŸskĂ© meno", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "OdstrĂĄniĆ„ pouĆŸĂ­vateÄŸskĂ© meno", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "TĂœmto sa odstrĂĄni vaĆĄe pouĆŸĂ­vateÄŸskĂ© meno a ostatnĂ­ pouĆŸĂ­vatelia ho budĂș mĂŽcĆ„ pouĆŸiĆ„. Ste si istĂœ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "TĂœmto sa odstrĂĄni vaĆĄe pouĆŸĂ­vateÄŸskĂ© meno a zruĆĄĂ­ sa vĂĄĆĄ QR kĂłd a odkaz. PouĆŸĂ­vateÄŸskĂ© meno „{username}“ bude k dispozĂ­cii pre ďalĆĄĂ­ch pouĆŸĂ­vateÄŸov. Naozaj chcete pokračovaĆ„?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "UĆŸ nebudete mĂŽcĆ„ zdieÄŸaĆ„ ani prezeraĆ„ prĂ­behy. BudĂș tieĆŸ odstrĂĄnenĂ© aktualizĂĄcie prĂ­behov, ktorĂ© ste nedĂĄvno zdieÄŸali.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Jazyk", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Jazyk", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "SystĂ©movĂœ jazyk", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "HÄŸadaĆ„ jazyky", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Ćœiadne vĂœsledky pre „{searchTerm}“", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "NastaviĆ„", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ReĆĄtartujte Signal na potvrdenie zmien", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Ak chcete zmeniĆ„ jazyk, musĂ­te reĆĄtartovaĆ„ aplikĂĄciu.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ReĆĄtartovaĆ„", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "AktualizĂĄcia na verziu {version} je k dispozĂ­cii", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Pri ukladanĂ­ vaĆĄich nastavenĂ­ sa vyskytla chyba. ProsĂ­m skĂșste to znova.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "SprĂĄva", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Viac ĆĄtĂœlov", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ResetovaĆ„", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Hotovo", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Farba odkazu pouĆŸĂ­vateÄŸskĂ©ho mena, {index,number} z {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Ak resetujete svoj QR kĂłd, vĂĄĆĄ existujĂșci QR kĂłd a odkaz uĆŸ nebudĂș fungovaĆ„.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Resetuje sa odkaz
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR kĂłd a odkaz nie sĂș nastavenĂ©. Skontrolujte svoje pripojenie a skĂșste to znova.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Nastavte si pouĆŸĂ­vateÄŸskĂ© meno Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "upravenĂ©", + "messageformat": "UpravenĂ©", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "OdoslaĆ„ znovu", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Viac akciĂ­", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Volania", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "NovĂœ hovor", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "NovĂœ hovor", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Viac akciĂ­", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "VymazaĆ„ histĂłriu hovorov", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "VymazaĆ„ histĂłriu hovorov?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "TĂœmto natrvalo vymaĆŸete celĂș histĂłriu hovorov", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ZmazaĆ„", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "HistĂłria hovorov vyčistenĂĄ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "KliknutĂ­m zobrazĂ­te alebo začnete hovor", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "HÄŸadaĆ„", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "FiltrovaĆ„ podÄŸa zmeĆĄkanĂœch", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "PrepnĂșĆ„", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ćœiadne nedĂĄvne hovory. Začnite zavolanĂ­m znĂĄmemu.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Ćœiadne vĂœsledky pre „{query}“", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "PrichĂĄdzajĂșci", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "OdchĂĄdzajĂșci", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ZmeĆĄkanĂœ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "SkupinovĂœ hovor", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ćœiadne nedĂĄvne konverzĂĄcie.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Ćœiadne vĂœsledky pre „{query}“", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {OdchĂĄdzajĂșci hlasovĂœ hovor} other {PrichĂĄdzajĂșci hlasovĂœ hovor}}} Video {{direction, select, Outgoing {OdchĂĄdzajĂșci videohovor} other {PrichĂĄdzajĂșci videohovor}}} Group {{direction, select, Outgoing {OdchĂĄdzajĂșci skupinovĂœ hovor} other {PrichĂĄdzajĂșci skupinovĂœ hovor}}} other {{direction, select, Outgoing {OdchĂĄdzajĂșci hovor} other {PrichĂĄdzajĂșci hovor}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ZmeĆĄkanĂœ hlasovĂœ hovor} Video {PrichĂĄdzajĂșci videohovor} Group {ZmeĆĄkanĂœ skupinovĂœ hovor} other {ZmeĆĄkanĂœ hovor}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {NeprijatĂœ hlasovĂœ hovor} Video {NeprijatĂœ videohovor} Group {NeprijatĂœ skupinovĂœ hovor} other {NeprijatĂœ hovor}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {OdmietnutĂœ hlasovĂœ hovor} Video {OdmietnutĂœ videohovor} Group {OdmietnutĂœ skupinovĂœ hovor} other {OdmietnutĂœ hovor}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ďalĆĄĂ­ pĂ­ĆĄe.} few {{count,number} ďalĆĄĂ­ pĂ­ĆĄu.} many {{count,number} ďalĆĄieho pĂ­ĆĄe.} other {{count,number} ďalĆĄĂ­ch pĂ­ĆĄe.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Čo je novĂ©", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "MalĂ© Ășpravy, opravy chĂœb a vylepĆĄenia vĂœkonu. Ďakujeme, ĆŸe pouĆŸĂ­vate Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "TĂĄto aktualizĂĄcia obsahuje niekoÄŸko vylepĆĄenĂ­ pre hlasovĂ© hovory a videohovory a niekoÄŸko menĆĄĂ­ch aktualizĂĄciĂ­ dokumentĂĄcie (ďakujeme, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Teraz mĂŽĆŸete zmeniĆ„ vybranĂœ jazyk v aplikĂĄcii Signal bez toho, aby ste zmenili nastavenia systĂ©mu (Nastavenia Signal > VzhÄŸad > Jazyk)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Aktualizovali sme niektorĂ© ikony upozornenĂ­ pre skupiny." + "icu:WhatsNew__v6.39--1": { + "messageformat": "OdstrĂĄnili sme krĂĄtke oneskorenie, ktorĂ© sa občas vyskytlo na macOS pri čakanĂ­ na pripojenie k hovoru." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Opravili sme animĂĄciu prechodu pre dlaĆŸdice videa, keď sa niekto pripojĂ­ alebo opustĂ­ skupinovĂœ hovor." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Teraz mĂŽĆŸete kliknĂșĆ„ na profilovĂș fotografiu alebo avatar skupiny v hlavičke četu pre rĂœchly prechod k nastaveniam četu alebo zobrazenie nepozretĂœch prĂ­behov z tohto četu. Ďakujeme, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/sl-SI/messages.json b/_locales/sl-SI/messages.json index 1d194a4ab4..465571e882 100644 --- a/_locales/sl-SI/messages.json +++ b/_locales/sl-SI/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Napaka v bazi podatkov", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "PriĆĄlo je do napake v zbirki podatkov. Napako lahko kopirate in se obrnete na podporo za Signal, da vam pomaga odpraviti teĆŸavo. Če morate Signal uporabiti takoj, lahko izbriĆĄete podatke in ga znova zaĆŸenete.\n\nObrnite se na podporo tako, da obiơčete: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { "messageformat": "Izbris vseh podatkov in ponovni zagon", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Ćœelite trajno izbrisati vse podatke?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Vsa vaĆĄa zgodovina sporočil in mediji bodo trajno izbrisani iz te naprave. Signal boste lahko uporabljali v tej napravi, ko jo znova poveĆŸete. S tem ne boste izbrisali nobenih podatkov iz svojega telefona.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Različica vaĆĄe zbirke podatkov se ne ujema s to različico Signala. Prepričajte se, da v računalniku odpirate najnovejĆĄo različico Signala.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Datoteka", @@ -300,6 +316,70 @@ "messageformat": "Klepeti", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Nekaj je ĆĄlo narobe z vaĆĄim uporabniĆĄkim imenom, ni več dodeljeno vaĆĄemu računu. Lahko ga poskusite znova nastaviti ali izberete novega.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Popravi", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Nekaj je ĆĄlo narobe z vaĆĄo QR kodo in vaĆĄa povezava z uporabniĆĄkim imenom ni več veljavna. Ustvarite novo povezavo za skupno rabo z drugimi.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Popravi", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "PrikaĆŸi zavihke", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Skrij zavihke", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "PriĆĄlo je do napake", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} neprebranih", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Označeno kot neprebrano", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Klepeti", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Klici", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Zgodbe", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Nastavitve", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Posodobite aplikacijo Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Nazaj", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Ti klepeti so arhivirani in se bodo v nabiralniku ponovno pojavili le ob prejemu novih sporočil.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Vseeno kliči", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Vseeno se pridruĆŸi", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Nadaljuj s klicem", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Varnostne ĆĄtevilke se posodabljajo.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Preberite več", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "PrejĆĄnja varnostna ĆĄtevilka", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Naslednja varnostna ĆĄtevilka", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Različica varnostne ĆĄtevilke, {index,number} od {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Označi kot potrjeno", @@ -663,33 +747,41 @@ "messageformat": "Izbris potrditve", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Če ĆŸelite preveriti ĆĄifriranje od-konca-do-konca z uporabnikom_co {name}, primerjajte zgornje ĆĄtevilke s tistimi na njegovi/njeni napravi. S svojo napravo lahko tudi skenira vaĆĄo kodo.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Preberite več", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Če ĆŸelite preveriti ĆĄifriranje od-konca-do-konca z uporabnikom_co {name}, poveĆŸite zgornjo barvno kartico z njegovo/njeno napravo in primerjajte ĆĄtevilki. Če se ne ujemata, podrsajte in poskusite z drugim parom varnostnih ĆĄtevilk. Samo en par se mora ujemati.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Če ĆŸelite preveriti ĆĄifriranje od-konca-do-konca z uporabnikom_co {name}, primerjajte zgornje ĆĄtevilke s tistimi na njegovi/njeni napravi. S svojo napravo lahko tudi skenira vaĆĄo kodo.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Spremembe varnostnih ĆĄtevilk", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Varnostne ĆĄtevilke se v prehodnem obdobju posodabljajo, da omogočijo prihajajoče funkcije zasebnosti v Signalu.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Če ĆŸelite preveriti varnostne ĆĄtevilke, uskladite barvno kartico z napravo vaĆĄega kontakta. Če se ne ujemata, podrsajte in poskusite z drugim parom varnostnih ĆĄtevilk. Samo en par se mora ujemati.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Potrebujete pomoč?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Razumem", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Varnostna ĆĄtevilka s to osebo bo ustvarjena, potem ko bo z vami izmenjala sporočila.", @@ -1267,10 +1359,6 @@ "messageformat": "Nedavne medijske datoteke", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Če ĆŸelite preveriti varnost ĆĄifriranja od-konca-do-konca z uporabnikom_co {name}, primerjajte gornje ĆĄtevilke s tistimi na njegovi/njeni napravi. Prav tako lahko skenira zgornjo QR kodo.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "S to osebo ĆĄe niste izmenjali sporočil. Vajino varnostno ĆĄtevilo bo na voljo po prvem poslanem sporočilu." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "IzbriĆĄi", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "IzbriĆĄi sporočila", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Ćœelite izbrisati klepet?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "IzbriĆĄem sporočila?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Ta klepet bo izbrisan s te naprave.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Sporočila v tem klepetu bodo izbrisana iz te naprave. Ko izbriĆĄete sporočila, lahko ĆĄe vedno iơčete ta klepet.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Zapusti skupino", @@ -1438,6 +1526,14 @@ "messageformat": "VaĆĄa zgodovina sporočil za oba klepeta je bila zdruĆŸena tukaj.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} pripada {conversationTitle}. Oba_e sta člana_ici {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} pripada {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Predogled slike citiranega sporočila", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ponovni klic", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Začni klic", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "PridruĆŸi se klicu", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofon je utiĆĄan zaradi obsega klica", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Obvestila o klicih", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Klic je polno zaseden", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "PridruĆŸi se", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Začni", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Klic je poln", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera onemogočena", @@ -1621,10 +1725,6 @@ "messageformat": "Vklop kamere", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "UtiĆĄaj", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon onemogočen", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Prekini utiĆĄanje", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Deli", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Predvajanje onemogočeno", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Zaključi predvajanje", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Zvonjenje", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Skupina je prevelika za zvonjenje vsem udeleĆŸencem.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Zvonjenje", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Izklopi zvonjenje", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Vključi zvonjenje", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Več moĆŸnosti", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Vi", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "VaĆĄa kamera je izključena", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Prikaz varnostne ĆĄtevilke", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Sporočilo", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Prikaz varnostne ĆĄtevilke", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Ne najdemo ĆĄtevilke. Preverite internetno povezavo in poskusite znova.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Urejanje je mogoče uporabiti samo v 3 urah od trenutka, ko ste poslali to sporočilo.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Urejanje je mogoče uporabiti samo v 24 urah od trenutka, ko ste poslali to sporočilo.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Sporočilo je bilo izbrisano.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Priloga je prevelika za prikaz.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Nekatere priloge so prevelike za prikaz.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Podatkov o donaciji ni mogoče pridobiti", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Samo Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Urejanje sporočil je na voljo samo uporabnikom Signala beta. Če uredite sporočilo, bo vidno samo ljudem, ki uporabljajo najnovejĆĄo različico Signala beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Uredi sporočilo", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Če uredite sporočilo, bo vidno samo ljudem, ki uporabljajo najnovejĆĄe različice Signala. Videli bodo lahko, da ste uredili sporočilo.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Dohodni video klic ...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Odhodni glasovni klic", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Odhodni video klic", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} vas kliče", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Ponovno povezovanje ...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} oseba} two {{count,number} osebi} few {{count,number} osebe} other {{count,number} ljudi}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Zvočni klic", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Končaj", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Zapusti", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon je izključen", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon je vključen", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zvonjenje je vključeno", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zvonjenje je izključeno", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Nastavitve", @@ -3468,13 +3668,25 @@ "messageformat": "Celostranski klic", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Preklop na mreĆŸni pogled", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Spremeni pogled", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Preklop na govorčev pogled", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "MreĆŸni pogled", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Pogled stranske vrstice", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Pogled govornika", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Pogled posodobljen", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Zapusti klic", @@ -3576,6 +3788,14 @@ "messageformat": "Okej", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Sporočila ni mogoče urediti", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "To sporočilo je mogoče urediti le {max,number}x.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Oprostite, ta povezava sgnl:// ni imela smisla!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "UporabniĆĄko ime", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Nekaj je ĆĄlo narobe z vaĆĄim uporabniĆĄkim imenom, ni več dodeljeno vaĆĄemu računu.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "IzbriĆĄi uporabniĆĄko ime", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Ustvarite uporabniĆĄko ime", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR koda ali povezava", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "UporabniĆĄko ime je treba ponastaviti", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Povezavo uporabniĆĄkega imena je treba ponastaviti", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Delite svoje uporabniĆĄko ime", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "IzbriĆĄi uporabniĆĄko ime", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "S tem ko boste izbrisali svoje uporabniĆĄko ime, si ga bo lahko prisvojil kdo drug. Ste prepričani?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "S tem boste odstranili svoje uporabniĆĄko ime ter onemogočili QR kodo in povezavo. “{username}” bo na voljo drugim. Ste prepričani?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Zgodb ne boste mogli več deliti ali si jih ogledovati. Izbrisane bodo tudi posodobitve zgodb, ki ste jih nedavno delili.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Jezik", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Jezik", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistemski jezik", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Iskanje jezikov", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Ni rezultatov za “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Nastavi", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Za uporabo znova zaĆŸenite Signal", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Za spremembo jezika se mora aplikacija znova zagnati.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ponovni zagon", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Na voljo je nadgradnja na različico {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "PriĆĄlo je do napake pri shranjevanju nastavitev. Poskusite znova.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Sporočilo", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Več stilov", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Ponastavi", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "OK", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Barva povezave uporabniĆĄkega imena, {index,number} od {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Če ponastavite svojo QR kodo, vaĆĄa obstoječa QR koda in povezava ne bosta več delovali.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Ponastavitev povezave ...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR koda in povezava nista nastavljeni. Preverite omreĆŸno povezavo in poskusite znova.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Nastavite svoje uporabniĆĄko ime za Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "urejeno", + "messageformat": "Urejeno", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Ponovno poĆĄlji", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Več dejanj", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Klici", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nov klic", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nov klic", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Več dejanj", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Počisti zgodovino klicev", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Ćœelite počistiti zgodovino klicev?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "S tem boste nepovratno izbrisali celotno zgodovino klicev", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "IzbriĆĄi", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Zgodovina klicev izbrisana", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klikni za ogled ali začetek klica", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Iskanje", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtriraj po zgreĆĄenih", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Vklop", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ni zadnjih klicev. Začnite tako, da pokličete prijatelja_ico.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Ni rezultatov za “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Dohodni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Odhodni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ZgreĆĄeni", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Skupinski klic", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ni nedavnih pogovorov.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Ni rezultatov za “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Odhodni glasovni klic} other {Dohodni glasovni klic}}} Video {{direction, select, Outgoing {Odhodni video klic} other {Dohodni video klic}}} Group {{direction, select, Outgoing {Odhodni skupinski klic} other {Dohodni skupinski klic}}} other {{direction, select, Outgoing {Odhodni klic} other {Dohodni klic}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ZgreĆĄen glasovni klic} Video {ZgreĆĄen video klic} Group {Neodgovorjen skupinski klic} other {Neodgovorjen klic}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Neodgovorjen glasovni klic} Video {Neodgovorjen video klic} Group {Neodgovorjen skupinski klic} other {Neodgovorjen klic}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Zavrnjen zvočni klic} Video {Zavrnjen video klic} Group {Zavrnjen skupinski klic} other {Zavrnjen klic}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {Ć e ena oseba tipka.} two {Ć e {count,number} osebi tipkata.} few {Ć e {count,number} osebe tipkajo.} other {Ć e {count,number} oseb tipka.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Kaj je novega", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Majhne prilagoditve, popravki napak in izboljĆĄave zmogljivosti. Hvala, da uporabljate Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ta posodobitev vključuje nekaj izboljĆĄav za zvočne in video klice ter nekaj manjĆĄih posodobitev dokumentacije (hvala, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Zdaj lahko spremenite izbrani jezik v Signalu, ne da bi spremenili sistemske nastavitve (Nastavitve signala > Videz > Jezik)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Spremenili smo ikone obvestil, ki se prikaĆŸejo za posodobitve skupine, na primer, ko se skupini pridruĆŸi nekdo nov. Te ikone pomagajo izboljĆĄati berljivost, ĆĄe posebej, če ĆŸivite v temi Temne teme. PrjeĆĄnje ikone so se komajda prilagodile temi. Nove ikone so bile rojene v njej, tema jih je oblikovala." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Popravili smo kratko zamudo, do katere je včasih priĆĄlo med pridruĆŸitvijo preddverju klicev v napravah macOS, kar bi moralo odpraviti vsaj en izgovor za polsekundno zamudo na sestanek." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Popravili smo animacijo prehoda za video ploơčice, ko se nekdo pridruĆŸi ali zapusti skupinski klic. Ko se pred vami prikaĆŸe prijateljev obraz, je to druĆŸbeno gibanje." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Zdaj lahko kliknete profilno fotografijo ali avatar skupine v glavi klepeta, da hitro dostopate do nastavitev klepeta ali si ogledate zgodbe iz tega klepeta, ki jih ĆĄe niste videli. Hvala, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/sq-AL/messages.json b/_locales/sq-AL/messages.json index 2af805b649..4ed60dcc4a 100644 --- a/_locales/sq-AL/messages.json +++ b/_locales/sq-AL/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Gabim Baze tĂ« DhĂ«nash", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Gabim nĂ« bazĂ«n e tĂ« dhĂ«nave. Mund ta kopjosh gabimin dhe tĂ« kontaktosh ekipin e mbĂ«shtetjes sĂ« Signal qĂ« tĂ« tĂ« ndihmojĂ« ta rregullosh problemin. NĂ«se duhet qĂ« ta pĂ«rdorĂ«sh Signal direkt, mund t'i fshish tĂ« dhĂ«nat dhe ta shkarkosh sĂ«rish.\n\nKontakto ekipin e mbĂ«shtetjes nĂ«: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Fshiji tĂ« gjitha tĂ« dhĂ«nat dhe rifillo", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Fshiji tĂ« dhĂ«nat dhe rinise", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "TĂ« fshihen pĂ«rgjithmonĂ« tĂ« gjitha tĂ« dhĂ«nat?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "I gjithĂ« historiku dhe media jote e mesazheve do tĂ« fshihen pĂ«rgjithmonĂ« nga kjo pajisje. Do tĂ« mund tĂ« pĂ«rdorĂ«sh Signal nĂ« kĂ«tĂ« pajisje pasi ta rilidhĂ«sh atĂ«. Kjo nuk do tĂ« fshijĂ« ndonjĂ« tĂ« dhĂ«nĂ« nga telefoni yt.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Versioni i bazĂ«s sĂ« tĂ« dhĂ«nave nuk pĂ«rputhet me kĂ«tĂ« version tĂ« Signal. Sigurohu qĂ« po hap versionin mĂ« tĂ« ri tĂ« Signal nĂ« kompjuterin tĂ«nd.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&KartelĂ«", @@ -300,6 +316,70 @@ "messageformat": "Bisedat", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Ndodhi njĂ« gabim me emrin tĂ«nd tĂ« pĂ«rdoruesit; nuk lidhet mĂ« me llogarinĂ« tĂ«nde. Mund tĂ« provosh dhe ta vendosĂ«sh sĂ«rish ose zgjidh njĂ« tĂ« ri.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Rregulloje tani", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Ndodhi njĂ« gabim me kodin QR dhe lidhjen e emrit tĂ« pĂ«rdoruesit; nuk janĂ« mĂ« tĂ« vlefshĂ«m. Krijo lidhje tĂ« re pĂ«r ta shpĂ«rndarĂ« me tĂ« tjerĂ«t.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Rregulloje tani", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Shfaq skedat", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Fshih skedat", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ka ndodhur njĂ« gabim", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} tĂ« palexuara", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "TĂ« shĂ«nuara si tĂ« palexuara", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Bisedat", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Thirrje", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Postimet e pĂ«rkohshme", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Rregullime", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "PĂ«rditĂ«soni Signal-in", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Mbrapsht", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "KĂ«to biseda janĂ« tĂ« arkivuara dhe do tĂ« shfaqen te kutia hyrĂ«se vetĂ«m nĂ«se vijnĂ« mesazhe tĂ« rinj.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Thirre, sido qoftĂ«", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Bashkohu, sidoqoftĂ«", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Vazhdoje Thirrjen", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Numrat e sigurisĂ« po pĂ«rditĂ«sohen.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "MĂ«soni mĂ« tepĂ«r", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Numri i mĂ«parshĂ«m i sigurisĂ«", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Numri tjetĂ«r i sigurisĂ«", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Versioni i numrit tĂ« sigurisĂ«, {index,number} nga {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "VĂ«ri shenjĂ« si i verifikuar", @@ -663,33 +747,41 @@ "messageformat": "Spastroje verifikimin", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "PĂ«r tĂ« verifikuar kodimin nga skaji nĂ« skaj me {name}, krahaso numrat e mĂ«sipĂ«rm me pajisjen e tyre. Ata gjithashtu mund tĂ« skanojnĂ« kodin tĂ«nd me pajisjen e tyre.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "MĂ«so mĂ« shumĂ«", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "PĂ«r tĂ« verifikuar kodimin nga skaji nĂ« skaj me {name}, pĂ«rputh kartĂ«n e mĂ«sipĂ«rme tĂ« ngjyrave me pajisjen e tyre dhe krahaso numrat. NĂ«se kĂ«to nuk pĂ«rputhen, provo çiftin tjetĂ«r tĂ« numrave tĂ« sigurisĂ«. VetĂ«m njĂ« palĂ« duhet tĂ« pĂ«rputhet.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "PĂ«r tĂ« verifikuar kodimin nga skaji nĂ« skaj me {name}, krahaso numrat e mĂ«sipĂ«rm me pajisjen e tyre. Ata gjithashtu mund tĂ« skanojnĂ« kodin tĂ«nd me pajisjen e tyre.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Ndryshimet nĂ« numrat e sigurisĂ«", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Numrat e sigurisĂ« po pĂ«rditĂ«sohen gjatĂ« njĂ« periudhe tranzicioni pĂ«r tĂ« aktivizuar veçoritĂ« e ardhshme tĂ« privatĂ«sisĂ« nĂ« Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "PĂ«r tĂ« verifikuar numrat e sigurisĂ«, pĂ«rputh kartĂ«n e ngjyrave me pajisjen e kontaktit tĂ«nd. NĂ«se kĂ«to nuk pĂ«rputhen, provo çiftin tjetĂ«r tĂ« numrave tĂ« sigurisĂ«. VetĂ«m njĂ« palĂ« duhet tĂ« pĂ«rputhet.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Ju duhet ndihmĂ«?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "E kuptova", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "NjĂ« numĂ«r sigurie do tĂ« krijohet me kĂ«tĂ« person pasi tĂ« shkĂ«mbeni mesazhe me tĂ«.", @@ -1267,10 +1359,6 @@ "messageformat": "Shihni media sĂ« fundi", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "PĂ«r tĂ« verifikuar sigurinĂ« e kodimit tĂ«nd nga skaji nĂ« skaj me {name}, krahaso numrat e mĂ«sipĂ«rm me pajisjen e tyre. Ata gjithashtu mund tĂ« skanojnĂ« kodin e mĂ«sipĂ«rm QR.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "S’keni shkĂ«mbyer ende ndonjĂ« mesazh me kĂ«tĂ« grup. Numri juaj i sigurisĂ« me tĂ« do tĂ« jetĂ« i passhĂ«m pas mesazhit tĂ« parĂ«." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Fshije", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Fshi mesazhet", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "TĂ« fshihet biseda?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "TĂ« fshihen mesazhet?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Kjo bisedĂ« do tĂ« fshihet nga kjo pajisjeje.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Mesazhet nĂ« kĂ«tĂ« bisedĂ« do tĂ« fshihen nga kjo pajisje. Mund ta kĂ«rkosh ende kĂ«tĂ« bisedĂ« pasi tĂ« fshish mesazhet.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Largohu nga grupi", @@ -1438,6 +1526,14 @@ "messageformat": "Historiku yt i mesazheve pĂ«r tĂ« dyja bisedat Ă«shtĂ« bashkuar kĂ«tu.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} i pĂ«rket {conversationTitle}. TĂ« dy ju jeni anĂ«tarĂ« tĂ« {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} i pĂ«rket {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "MiniaturĂ« e figurĂ«s nga mesazhi i cituar", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Rithirre", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Nise Thirrjen", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Hyni nĂ« Thirrje", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofoni Ă«shtĂ« pa zĂ« pĂ«r shkak tĂ« numrit tĂ« madh tĂ« pjesĂ«marrĂ«sve nĂ« thirrje", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Njoftimet e thirrjes", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Thirrja Ă«shtĂ« plot", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "KamerĂ«", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Bashkohu", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Fillo", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Thirrja plot", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera e çaktivizuar", @@ -1621,10 +1725,6 @@ "messageformat": "Ndize kamerĂ«n", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Hiqi zĂ«rin", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon i çaktivizuar", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ktheji zĂ«rin mikrofonit", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Ndajeni Me tĂ« TjerĂ«", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Paraqitje e çaktivizuar", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Ndal paraqitje", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Bjeri ziles", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grupi Ă«shtĂ« shumĂ« i madh pĂ«r t’u rĂ«nĂ« ziles sĂ« pjesĂ«marrĂ«sve.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Aktivizo rĂ«nien e ziles", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Çaktivizo zilen", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Aktivizo zilen", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Opsione tĂ« tjera", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Ti", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kamera juaj Ă«shtĂ« e fikur", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Shih Numrin e SigurisĂ«", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mesazh", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Shih Numrin e SigurisĂ«", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "S’u arrit tĂ« sillej numĂ«r telefoni. Kontrolloni lidhjen tuaj dhe riprovoni.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Ndryshimet mund tĂ« zbatohen vetĂ«m brenda 3 orĂ«ve nga momenti qĂ« dĂ«rgove kĂ«tĂ« mesazh.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "PĂ«rpunimet mund tĂ« zbatohen vetĂ«m brenda 24 orĂ«ve nga momenti qĂ« dĂ«rgove kĂ«tĂ« mesazh.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ky mesazh u fshi.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "BashkĂ«ngjitja Ă«shtĂ« shumĂ« e madhe pĂ«r t'u shfaqur.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Disa bashkĂ«ngjitje janĂ« shumĂ« tĂ« mĂ«dha pĂ«r t'u shfaqur.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Detajet e dhurimit nuk mund tĂ« shfaqen", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "VetĂ«m Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "PĂ«rpunimi i mesazheve Ă«shtĂ« i disponueshĂ«m vetĂ«m pĂ«r pĂ«rdoruesit e Signal beta. NĂ«se pĂ«rpunon njĂ« mesazh, ai do tĂ« jetĂ« i dukshĂ«m vetĂ«m pĂ«r personat qĂ« kanĂ« versionin mĂ« tĂ« fundit tĂ« Signal beta.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "PĂ«rpuno mesazhin", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "NĂ«se pĂ«rpunon njĂ« mesazh, ai do tĂ« jetĂ« i dukshĂ«m vetĂ«m pĂ«r personat qĂ« kanĂ« versionin mĂ« tĂ« fundit tĂ« Signal. Ata do shohin se ti ke redaktuar njĂ« mesazh.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Thirrje video ardhĂ«se
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Thirrje zanore dalĂ«se", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Thirrje video nga ju", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} po ju thĂ«rret", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Po rilidhet
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} person} other {{count,number} persona}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Thirrje me audio", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "PĂ«rfundo", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Largohu", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofoni i fikur", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofoni i ndezur", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Po bie zilja", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zilja nuk po bie", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Rregullime", @@ -3468,13 +3668,25 @@ "messageformat": "Thirrje sa krejt ekrani", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Kalo nĂ«n pamjen rrjetĂ«", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Ndrysho pamjen", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Kalo nĂ«n pamjen folĂ«s", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Pamje rrjetĂ«", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Pamje me kolona", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Pamje me nĂ« qendĂ«r folĂ«sin", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Pamja e pĂ«rditĂ«suar", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Dilni nga thirrja", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Mesazhi nuk mund tĂ« modifikohet", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Mesazhi mund tĂ« modifikohet vetĂ«m {max,number} herĂ«.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Na ndjeni, kjo lidhje sgnl:// s’ka kuptim!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "EmĂ«r pĂ«rdoruesi", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Ndodhi njĂ« gabim me emrin tĂ«nd tĂ« pĂ«rdoruesit; nuk lidhet mĂ« me llogarinĂ« tĂ«nde.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Fshije emrin e pĂ«rdoruesit", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Krijoni EmĂ«r PĂ«rdoruesi", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Kodi QR ose lidhja", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Emri i pĂ«rdoruesit duhet tĂ« rivendoset", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Lidhja e emrit tĂ« pĂ«rdoruesit duhet tĂ« rivendoset", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ShpĂ«rndaj emrin tĂ«nd tĂ« pĂ«rdoruesit", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Fshije emrin e pĂ«rdoruesit", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Kjo do tĂ« heqĂ« emrin e pĂ«rdoruesit, duke u lejuar pĂ«rdoruesve tĂ« tjerĂ« ta pĂ«rdorin. Je i sigurt?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Kjo do tĂ« heqĂ« emrin tĂ«nd tĂ« pĂ«rdoruesit dhe do tĂ« çaktivizojĂ« kodin QR dhe lidhjen tĂ«nde. \"{username}\" do tĂ« jetĂ« i disponueshĂ«m pĂ«r tu pĂ«rdorur nga tĂ« tjerĂ«t. Je i sigurt?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Nuk do tĂ« mund tĂ« ndash apo shikosh mĂ« postime tĂ« pĂ«rkohshme. PĂ«rditĂ«simet e postimeve tĂ« pĂ«rkohshme qĂ« ke ndarĂ« sĂ« fundi do tĂ« fshihen gjithashtu.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Gjuha", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Gjuha", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Gjuha e sistemit", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "KĂ«rko gjuhĂ«t", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Nuk ka rezultate pĂ«r \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Cakto", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Rihap Signal qĂ« tĂ« reflektohen ndryshimet", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "PĂ«r tĂ« ndryshuar gjuhĂ«n, aplikacioni duhet tĂ« rihapet.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Rihap", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Ka tĂ« gatshĂ«m pĂ«rditĂ«sim me versionin {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Pati njĂ« gabim teksa ruheshin rregullimet tuaja. Ju lutemi, riprovoni.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mesazh", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "MĂ« shumĂ« lloje", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Riktheje", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "U bĂ«", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Ngjyra e lidhjes sĂ« emrit tĂ« pĂ«rdoruesit, {index,number} nga {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "NĂ«se rivendos kodin QR, kodi QR dhe lidhja ekzistuese nuk do tĂ« funksionojnĂ« mĂ«.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Po rivendoset lidhja...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Kodi QR dhe lidhja nuk janĂ« vendosur. Kontrollo lidhjen e rrjetit dhe provo sĂ«rish.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Vendos emrin tĂ«nd tĂ« pĂ«rdoruesit nĂ« Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "i redaktuar", + "messageformat": "I redaktuar", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "RidĂ«rgoje", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "MĂ« tepĂ«r veprime", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Thirrje", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Thirrje e re", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Thirrje e re", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "MĂ« tepĂ«r veprime", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Pastro historikun e thirrjeve", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "TĂ« pastrohet historiku i thirrjeve?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Kjo do tĂ« fshijĂ« pĂ«rgjithmonĂ« tĂ« gjithĂ« historikun e thirrjeve", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Spastroje", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Historia e thirrjeve u fshi", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Kliko pĂ«r tĂ« parĂ« ose nisur njĂ« telefonatĂ«", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "KĂ«rko", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtro sipas \"tĂ« humburat\"", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Shfaqe/Fshihe", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Nuk ka thirrje sĂ« voni. Fillo duke telefonuar njĂ« mik.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Nuk ka rezultate pĂ«r \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "HyrĂ«se", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "DalĂ«se", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "E humbur", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Thirrje grupi", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Nuk ka biseda tĂ« fundit.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Nuk ka rezultate pĂ«r \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Thirrje zanore dalĂ«se} other {Thirrje zanore hyrĂ«se}}} Video {{direction, select, Outgoing {Thirrje video nga ju} other {Thirrje video ardhĂ«se}}} Group {{direction, select, Outgoing {Thirrje dalĂ«se nĂ« grup} other {Thirrje hyrĂ«se nĂ« grup}}} other {{direction, select, Outgoing {Thirrje nga ju} other {Thirrje ardhĂ«se}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Thirrje zanore e humbur} Video {HumbĂ«t thirrje video} Group {Thirrje e humbur nĂ« grup} other {Thirrje e humbur}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Thirrje zanore pa pĂ«rgjigje} Video {Thirrje video pa pĂ«rgjigje} Group {Thirrje nĂ« grup pa pĂ«rgjigje} other {Thirrje pa pĂ«rgjigje}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Thirrje zanore e refuzuar} Video {Thirrje me video e refuzuar} Group {Thirrje nĂ« grup e refuzuar} other {Thirrje e refuzuar}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} tjetĂ«r po shkruan.} other {{count,number} tjerĂ« po shkruajnĂ«.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Ç’ka tĂ« Re", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Rregullme tĂ« vogla, riparime tĂ« gabimeve dhe pĂ«rmirĂ«sime tĂ« mbarĂ«vajtjes. Faleminderit qĂ« pĂ«rdorni Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ky pĂ«rditĂ«sim pĂ«rfshin disa pĂ«rmirĂ«sime pĂ«r thirrjet zanore e video dhe disa pĂ«rditĂ«sime tĂ« vogla dokumentacioni (faleminderit, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Tani mund ta ndryshosh gjuhĂ«n e zgjedhur nĂ« Signal pa ndryshuar cilĂ«simet e sistemit (CilĂ«simet e Signal > Pamja > Gjuha)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Ne pĂ«rditĂ«suam disa ikona tĂ« njoftimeve tĂ« grupit. Modifikuam ikonat e njoftimeve qĂ« shfaqen pĂ«r pĂ«rditĂ«simet e grupit, si pĂ«r shembull, kur njĂ« person i ri i bashkohet njĂ« grupi. KĂ«to ikona ndihmojnĂ« nĂ« pĂ«rmirĂ«simin e lexueshmĂ«risĂ«, veçanĂ«risht nĂ«se pĂ«rdorni errĂ«sirĂ«n e TemĂ«s sĂ« ErrĂ«t. Ikonat e mĂ«parshme thjesht u pĂ«rshtatĂ«n me errĂ«sirĂ«n. Ikonat e reja lindĂ«n nĂ« tĂ«, tĂ« krijuara prej saj." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Vonesa e shkurtĂ«r qĂ« shkaktohej ndonjĂ«herĂ« nĂ« pajisjet macOS teksa i bashkoheshit thirrjeve nĂ« zonĂ«n virtuale pritĂ«se Ă«shtĂ« rregulluar, gjĂ« e cila duhet tĂ« mos justifikojĂ« mĂ« tĂ« paktĂ«n njĂ« arsye lidhur me vonesĂ«n prej gjysmĂ« sekonde nĂ« takim." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Kemi rregulluar efektin e animimit tĂ« kalimit nga njĂ« ndarje nĂ« njĂ« ndarje tjetĂ«r tĂ« ekranit tĂ« videos kur dikush bashkohet ose largohet nga njĂ« telefonatĂ« nĂ« grup. TĂ« shohĂ«sh fytyrĂ«n e njĂ« miku qĂ« tĂ« shfaqet nĂ« ekran quhet lĂ«vizje shoqĂ«rore." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Tani mund tĂ« klikosh nĂ« njĂ« foto profili ose nĂ« njĂ« avatar grupi nĂ« krye tĂ« bisedĂ«s pĂ«r tĂ« hyrĂ« shpejt te cilĂ«simet e bisedĂ«s ose pĂ«r tĂ« parĂ« postime qĂ« ende nuk i keni parĂ« nga ajo bisedĂ«. Faleminderit, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/sr/messages.json b/_locales/sr/messages.json index b5b7fc2684..0e6fde5c4c 100644 --- a/_locales/sr/messages.json +++ b/_locales/sr/messages.json @@ -17,7 +17,7 @@ ] }, "icu:AddCaptionModal__title": { - "messageformat": "Đ”ĐŸĐŽĐ°Ń˜Ń‚Đ” ĐżĐŸŃ€ŃƒĐșу", + "messageformat": "ĐŁĐœĐ”ŃĐžŃ‚Đ” ĐżĐŸŃ€ŃƒĐșу", "description": "Shown as the title of the dialog that allows you to add a caption to a story" }, "icu:AddCaptionModal__placeholder": { @@ -73,7 +73,7 @@ "description": "Shown below the group name when selecting a group to invite a contact to, when the group item is disabled" }, "icu:Preferences__sent-media-quality": { - "messageformat": "КĐČалОтДт ŃĐ»Đ°ĐœĐŸĐł ĐŒĐ”ĐŽĐžŃ˜Đ°", + "messageformat": "КĐČалОтДт ĐżĐŸŃĐ»Đ°Ń‚ĐŸĐł ĐŒĐ”ĐŽĐžŃ˜Đ°", "description": "Title for the sent media quality setting" }, "icu:sentMediaQualityStandard": { @@ -110,14 +110,30 @@ }, "icu:databaseError": { "messageformat": "Đ“Ń€Đ”ŃˆĐșа у базО", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ДДсОла сД ĐłŃ€Đ”ŃˆĐșа са Đ±Đ°Đ·ĐŸĐŒ ĐżĐŸĐŽĐ°Ń‚Đ°Đșа. ĐœĐŸĐ¶Đ”Ń‚Đ” Ўа ĐșĐŸĐżĐžŃ€Đ°Ń‚Đ” ĐłŃ€Đ”ŃˆĐșу Đž ĐŸĐ±Ń€Đ°Ń‚ĐžŃ‚Đ” сД ĐżĐŸĐŽŃ€ŃˆŃ†Đž за Signal Ўа ĐŽĐŸĐżŃ€ĐžĐœĐ”ŃĐ”Ń‚Đ” Ń€Đ”ŃˆĐ°ĐČању ĐżŃ€ĐŸĐ±Đ»Đ”ĐŒĐ°. АĐșĐŸ жДлОтД ĐŸĐŽĐŒĐ°Ń… Ўа ĐșĐŸŃ€ĐžŃŃ‚ĐžŃ‚Đ” Signal, ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ĐżĐŸĐŽĐ°Ń‚ĐșĐ” Đž ĐżĐŸĐœĐŸĐČĐŸ ĐżĐŸĐșŃ€Đ”ĐœĐ”Ń‚Đ” аплОĐșацоју.\n\nОбратОтД сД ĐżĐŸĐŽŃ€ŃˆŃ†Đž таĐșĐŸ ŃˆŃ‚ĐŸ ћДтД ĐżĐŸŃĐ”Ń‚ĐžŃ‚Đž: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐžŃ‚Đ” сĐČĐ” ĐżĐŸĐŽĐ°Ń‚ĐșĐ” Đž ĐżĐŸĐœĐŸĐČĐŸ ĐżĐŸĐșŃ€Đ”ĐœĐžŃ‚Đ”", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐžŃ‚Đ” ĐżĐŸĐŽĐ°Ń‚ĐșĐ” Đž ĐżĐŸĐœĐŸĐČĐŸ ĐżĐŸĐșŃ€Đ”ĐœĐžŃ‚Đ” аплОĐșацоју", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ЖДлОтД лО Ўа Ń‚Ń€Đ°Ń˜ĐœĐŸ ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” сĐČĐ” ĐżĐŸĐŽĐ°Ń‚ĐșĐ”?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Ваша Ń†Đ”Đ»ĐŸĐșŃƒĐżĐœĐ° ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Đ° ĐżĐŸŃ€ŃƒĐșа Đž ŃĐ°ĐŽŃ€Đ¶Đ°Ń˜Đž бОћД Ń‚Ń€Đ°Ń˜ĐœĐŸ ĐžĐ·Đ±Ń€ĐžŃĐ°ĐœĐž са ĐŸĐČĐŸĐł ŃƒŃ€Đ”Ń’Đ°Ń˜Đ°. ĐœĐŸŃ›Đž ћДтД Ўа ĐșĐŸŃ€ĐžŃŃ‚ĐžŃ‚Đ” Signal ĐœĐ° ĐŸĐČĐŸĐŒ ŃƒŃ€Đ”Ń’Đ°Ń˜Ńƒ ĐœĐ°ĐșĐŸĐœ ŃˆŃ‚ĐŸ га ĐżĐŸĐœĐŸĐČĐŸ ĐżĐŸĐČДжДтД. ĐąĐžĐŒĐ” ĐœĐ”Ń›Đ”Ń‚Đ” ОзбрОсатО ĐœĐžĐșаĐșĐČĐ” ĐżĐŸĐŽĐ°Ń‚ĐșĐ” са Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ°.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Đ’Đ”Ń€Đ·ĐžŃ˜Đ° ĐČашД базД ĐżĐŸĐŽĐ°Ń‚Đ°Đșа ĐœĐ” ĐŸĐŽĐłĐŸĐČара ĐŸĐČĐŸŃ˜ ĐČĐ”Ń€Đ·ĐžŃ˜Đž Signal-а. ĐŸŃ€ĐŸĐČДрОтД Ўа лО стД ĐŸŃ‚ĐČĐŸŃ€ĐžĐ»Đž ĐœĐ°Ń˜ĐœĐŸĐČОју ĐČĐ”Ń€Đ·ĐžŃ˜Ńƒ Signal-а ĐœĐ° Ń€Đ°Ń‡ŃƒĐœĐ°Ń€Ńƒ.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { - "messageformat": "&Fajl", + "messageformat": "&Ѐајл", "description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt- combination." }, "icu:mainMenuCreateStickers": { @@ -300,6 +316,70 @@ "messageformat": "ЋасĐșања", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ĐĐ”ŃˆŃ‚ĐŸ ĐœĐžŃ˜Đ” у Ń€Đ”ĐŽŃƒ са ĐČĐ°ŃˆĐžĐŒ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐžĐŒ ĐžĐŒĐ”ĐœĐŸĐŒ – ĐČОшД ĐœĐžŃ˜Đ” ĐżĐŸĐČĐ”Đ·Đ°ĐœĐŸ са ĐČĐ°ŃˆĐžĐŒ ĐœĐ°Đ»ĐŸĐłĐŸĐŒ. ĐœĐŸĐ¶Đ”Ń‚Đ” ĐżĐŸĐșушато ĐżĐŸĐœĐŸĐČĐŸ Ўа га ĐżĐŸĐŽĐ”ŃĐžŃ‚Đ” ОлО Ўа ОзабДрДтД ĐœĐŸĐČĐŸ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ИспраĐČОтД саЎ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ĐĐ”ŃˆŃ‚ĐŸ ĐœĐžŃ˜Đ” у Ń€Đ”ĐŽŃƒ са QR ĐșĐŸĐŽĐŸĐŒ Đž Đ»ĐžĐœĐșĐŸĐŒ ĐżĐŸĐČĐ”Đ·Đ°ĐœĐžĐŒ са ĐČĐ°ŃˆĐžĐŒ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐžĐŒ ĐžĐŒĐ”ĐœĐŸĐŒ – ĐČОшД ĐœĐžŃŃƒ ĐČажДћО. ĐšŃ€Đ”ĐžŃ€Đ°Ń˜Ń‚Đ” ĐœĐŸĐČĐž Đ»ĐžĐœĐș ĐșĐŸŃ˜Đž ћДтД ĐżĐŸĐŽĐ”Đ»ĐžŃ‚Đž са ĐŽŃ€ŃƒĐłĐžĐŒĐ°.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ИспраĐČОтД саЎ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ПроĐșажО ĐșартОцД", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ХаĐșрој ĐșартОцД", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Đ”ĐŸŃˆĐ»ĐŸ јД ĐŽĐŸ ĐłŃ€Đ”ŃˆĐșĐ”", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "ĐĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐžŃ… ĐżĐŸŃ€ŃƒĐșа: {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ĐžĐ·ĐœĐ°Ń‡Đ”ĐœĐŸ ĐșĐ°ĐŸ ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐŸ", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ЋасĐșања", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ĐŸĐŸĐ·ĐžĐČĐž", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ĐŸŃ€ĐžŃ‡Đ”", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐŸĐŸĐŽĐ”ŃˆĐ°ĐČања", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ĐĐ¶ŃƒŃ€ĐžŃ€Đ°Ń˜Ń‚Đ” Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„ĐžĐ»", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ĐĐ°Đ·Đ°ĐŽ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ОĐČа ћасĐșања су архоĐČĐžŃ€Đ°ĐœĐ° Đž у ĐżĐŸŃ€ŃƒĐșĐ°ĐŒĐ° ћД сД ĐżĐŸŃ˜Đ°ĐČото ŃĐ°ĐŒĐŸ аĐșĐŸ ĐČĐ°ĐŒ ŃŃ‚ĐžĐłĐœŃƒ ĐœĐŸĐČĐ” ĐżĐŸŃ€ŃƒĐșĐ”.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -385,7 +465,7 @@ "description": "Button to allow the user to find a folder on disk" }, "icu:chooseFile": { - "messageformat": "Izaberite fajl", + "messageformat": "Đ˜Đ·Đ°Đ±Đ”Ń€ĐžŃ‚Đ” Ń„Đ°Ń˜Đ»", "description": "Button to allow the user to find a file on disk" }, "icu:loadDataHeader": { @@ -576,6 +656,10 @@ "messageformat": "ĐĐ”ĐŒĐ° ĐČДзД, ĐżĐŸĐ·ĐŸĐČĐž", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ĐĄĐČĐ”Ń˜Đ”ĐŽĐœĐŸ сД ĐżŃ€ĐžĐŽŃ€ŃƒĐ¶ĐžŃ‚Đ”", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "НастаĐČĐž ĐżĐŸĐ·ĐžĐČ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Đ‘Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜Đ”ĐČĐž сД Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°Ń˜Ńƒ.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ĐĄĐ°Đ·ĐœĐ°Ń˜ ĐČОшД", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐŸŃ€Đ”Ń‚Ń…ĐŸĐŽĐœĐž ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ХлДЎДћО ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Đ’Đ”Ń€Đ·ĐžŃ˜Đ° ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐŸĐł Đ±Ń€ĐŸŃ˜Đ°, {index,number} ОлО {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ĐžĐ·ĐœĐ°Ń‡Đž ĐșĐ°ĐŸ ĐżŃ€ĐŸĐČĐ”Ń€Đ”ĐœĐŸ", @@ -663,33 +747,41 @@ "messageformat": "ĐŁĐșĐ»ĐŸĐœĐž ĐŸĐČĐ”Ń€Ńƒ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "РаЎО ĐČДрОфОĐșĐ°Ń†ĐžŃ˜Đ” end-to-end ŃˆĐžŃ„Ń€ĐŸĐČања са ĐșĐŸĐœŃ‚Đ°ĐșŃ‚ĐŸĐŒ {name}, ŃƒĐżĐŸŃ€Đ”ĐŽĐžŃ‚Đ” ĐłĐŸŃ€Đ” проĐșĐ°Đ·Đ°ĐœĐ” Đ±Ń€ĐŸŃ˜Đ”ĐČĐ” с ŃƒŃ€Đ”Ń’Đ°Ń˜Đ”ĐŒ ĐČашДг ĐșĐŸĐœŃ‚Đ°Đșта. Ваш ĐșĐŸĐœŃ‚Đ°Đșт таĐșĐŸŃ’Đ” ĐŒĐŸĐ¶Đ” сĐČĐŸŃ˜ĐžĐŒ ŃƒŃ€Đ”Ń’Đ°Ń˜Đ”ĐŒ сĐșĐ”ĐœĐžŃ€Đ°Ń‚Đž ĐČаш ĐșĂŽĐŽ.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ĐĄĐ°Đ·ĐœĐ°Ń˜Ń‚Đ” ĐČОшД", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "РаЎО ĐČДрОфОĐșĐ°Ń†ĐžŃ˜Đ” end-to-end ŃˆĐžŃ„Ń€ĐŸĐČања са ĐșĐŸĐœŃ‚Đ°ĐșŃ‚ĐŸĐŒ {name}, ĐżĐŸĐČДжОтД Đșартоцу у Đ±ĐŸŃ˜Đž с ŃƒŃ€Đ”Ń’Đ°Ń˜Đ”ĐŒ ĐČашДг ĐșĐŸĐœŃ‚Đ°Đșта Đž ŃƒĐżĐŸŃ€Đ”ĐŽĐžŃ‚Đ” Đ±Ń€ĐŸŃ˜Đ”ĐČĐ”. АĐșĐŸ сД ĐœĐ” слажу, ĐżĐŸĐșŃƒŃˆĐ°Ń˜Ń‚Đ” с ĐŽŃ€ŃƒĐłĐžĐŒ ĐżĐ°Ń€ĐŸĐŒ ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐžŃ… Đ±Ń€ĐŸŃ˜Đ”ĐČа. Đ”ĐŸĐČĐŸŃ™ĐœĐŸ јД Ўа сД ĐżĐŸĐČДжД Ń˜Đ”ĐŽĐ°Đœ пар.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "РаЎО ĐČДрОфОĐșĐ°Ń†ĐžŃ˜Đ” end-to-end ŃˆĐžŃ„Ń€ĐŸĐČања са ĐșĐŸĐœŃ‚Đ°ĐșŃ‚ĐŸĐŒ {name}, ŃƒĐżĐŸŃ€Đ”ĐŽĐžŃ‚Đ” ĐłĐŸŃ€Đ” проĐșĐ°Đ·Đ°ĐœĐ” Đ±Ń€ĐŸŃ˜Đ”ĐČĐ” с ŃƒŃ€Đ”Ń’Đ°Ń˜Đ”ĐŒ ĐČашДг ĐșĐŸĐœŃ‚Đ°Đșта. Ваш ĐșĐŸĐœŃ‚Đ°Đșт таĐșĐŸŃ’Đ” ĐŒĐŸĐ¶Đ” сĐČĐŸŃ˜ĐžĐŒ ŃƒŃ€Đ”Ń’Đ°Ń˜Đ”ĐŒ сĐșĐ”ĐœĐžŃ€Đ°Ń‚Đž ĐČаш ĐșĂŽĐŽ.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ĐŸŃ€ĐŸĐŒĐ”ĐœĐ° у Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐ” Đ±Ń€ĐŸŃ˜Đ”ĐČĐ”", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ĐąĐŸĐșĐŸĐŒ ĐżŃ€Đ”Đ»Đ°Đ·ĐœĐŸĐł ĐżĐ”Ń€ĐžĐŸĐŽĐ° Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°Ń˜Ńƒ сД Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜Đ”ĐČĐž, ĐșаĐșĐŸ бО сД ĐŸĐŒĐŸĐłŃƒŃ›ĐžĐ»Đ” Đ±ŃƒĐŽŃƒŃ›Đ” ĐŸĐżŃ†ĐžŃ˜Đ” за проĐČĐ°Ń‚ĐœĐŸŃŃ‚ ĐœĐ° ĐżĐ»Đ°Ń‚Ń„ĐŸŃ€ĐŒĐž Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "РаЎО ĐČДрОфОĐșĐ°Ń†ĐžŃ˜Đ” Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐžŃ… Đ±Ń€ĐŸŃ˜Đ”ĐČа, ĐżĐŸĐČДжОтД Đșартоцу у Đ±ĐŸŃ˜Đž са ŃƒŃ€Đ”Ń’Đ°Ń˜Đ”ĐŒ ĐČашДг ĐșĐŸĐœŃ‚Đ°Đșта. АĐșĐŸ сД ĐœĐ” слажу, ĐżĐŸĐșŃƒŃˆĐ°Ń˜Ń‚Đ” с ĐŽŃ€ŃƒĐłĐžĐŒ ĐżĐ°Ń€ĐŸĐŒ ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐžŃ… Đ±Ń€ĐŸŃ˜Đ”ĐČа. Đ”ĐŸĐČĐŸŃ™ĐœĐŸ јД Ўа сД ĐżĐŸĐČДжД Ń˜Đ”ĐŽĐ°Đœ пар.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ĐŸĐŸŃ‚Ń€Đ”Đ±ĐœĐ° ĐČĐ°ĐŒ јД ĐżĐŸĐŒĐŸŃ›?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Đ Đ°Đ·ŃƒĐŒĐ”ĐŒ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Ха ĐŸĐČĐŸĐŒ ĐŸŃĐŸĐ±ĐŸĐŒ бОћД ĐșŃ€Đ”ĐžŃ€Đ°Đœ Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜ ĐœĐ°ĐșĐŸĐœ ŃˆŃ‚ĐŸ с ŃšĐŸĐŒ Ń€Đ°Đ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€ŃƒĐșĐ”.", @@ -765,7 +857,7 @@ "description": "Hover text for attachment filenames" }, "icu:unnamedFile": { - "messageformat": "Fajl bez naziva", + "messageformat": "Ѐајл бДз ĐœĐ°Đ·ĐžĐČа", "description": "Hover text for attachment filenames" }, "icu:voiceMessage": { @@ -817,7 +909,7 @@ "description": "An error popup when the user has attempted to add an attachment" }, "icu:fileSizeWarning": { - "messageformat": "Izabrani fajl prevazilazi ograničenja u pogledu veličine poruke. {limit,number} {units}", + "messageformat": "Đ˜Đ·Đ°Đ±Ń€Đ°ĐœĐž Ń„Đ°Ń˜Đ» прДĐČазОлазО ĐŸĐłŃ€Đ°ĐœĐžŃ‡Đ”ŃšĐ° у ĐżĐŸĐłĐ»Đ”ĐŽŃƒ ĐČĐ”Đ»ĐžŃ‡ĐžĐœĐ” ĐżĐŸŃ€ŃƒĐșĐ”. {limit,number} {units}", "description": "Shown in a toast if the user tries to attach too-large file" }, "icu:unableToLoadAttachment": { @@ -1267,10 +1359,6 @@ "messageformat": "ĐŸĐŸĐłĐ»Đ”ĐŽĐ°Ń˜Ń‚Đ” ĐœĐ”ĐŽĐ°ĐČĐœĐ” ĐŒĐ”ĐŽĐžŃ˜Đ”", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "РаЎО ĐżŃ€ĐŸĐČДрД Đ±Đ”Đ·Đ±Đ”ĐŽĐœĐŸŃŃ‚Đž ĐČашД end-to-end Đ”ĐœĐșŃ€ĐžĐżŃ†ĐžŃ˜Đ” са ĐșĐŸŃ€ĐžŃĐœĐžĐșĐŸĐŒ {name}, ŃƒĐżĐŸŃ€Đ”ĐŽĐžŃ‚Đ” ĐłĐŸŃ€Đ” проĐșĐ°Đ·Đ°ĐœĐ” Đ±Ń€ĐŸŃ˜Đ”ĐČĐ” са Đ±Ń€ĐŸŃ˜Đ”ĐČĐžĐŒĐ° ĐœĐ° ŃƒŃ€Đ”Ń’Đ°Ń˜Ńƒ ĐČашДг ĐșĐŸĐœŃ‚Đ°Đșта. Ваш ĐșĐŸĐœŃ‚Đ°Đșт таĐșĐŸŃ’Đ” ĐŒĐŸĐ¶Đ” сĐșĐ”ĐœĐžŃ€Đ°Ń‚Đž ĐłĐŸŃ€Đ” проĐșĐ°Đ·Đ°ĐœĐž qr ĐșĂŽĐŽ.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ĐœĐŸŃ€Đ°Ń‚Đ” Ń€Đ°Đ·ĐŒĐ”ĐœĐžŃ‚Đž бар Ń˜Đ”ĐŽĐœŃƒ ĐżĐŸŃ€ŃƒĐșу са ĐŸĐČĐžĐŒ ĐŽĐŸĐżĐžŃĐœĐžĐșĐŸĐŒ. йофра за ĐŽĐŸĐżĐžŃĐžĐČањД ћД сД стĐČĐŸŃ€ĐžŃ‚Đž ĐœĐ°ĐșĐŸĐœ прĐČĐ” прДпОсĐșĐ”." }, @@ -1334,17 +1422,17 @@ "messageformat": "Đ˜ĐœŃ„ĐŸ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ĐżĐŸŃ€ŃƒĐșĐ”", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ЖДлОтД лО Ўа ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ћасĐșањД?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ЖДлОтД лО Ўа ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ĐżĐŸŃ€ŃƒĐșу?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ЋасĐșањД ћД бОтО ĐžĐ·Đ±Ń€ĐžŃĐ°ĐœĐŸ са ĐŸĐČĐŸĐł ŃƒŃ€Đ”Ń’Đ°Ń˜Đ°.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ĐŸĐŸŃ€ŃƒĐșĐ” у ĐŸĐČĐŸĐŒ ћасĐșању ћД бОтО ĐžĐ·Đ±Ń€ĐžŃĐ°ĐœĐ” са ĐŸĐČĐŸĐł ŃƒŃ€Đ”Ń’Đ°Ń˜Đ°. И ЎаљД ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа тражОтД ĐŸĐČĐŸ ћасĐșањД ĐœĐ°ĐșĐŸĐœ ŃˆŃ‚ĐŸ ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ĐżĐŸŃ€ŃƒĐșĐ”.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Напусто групу", @@ -1438,6 +1526,14 @@ "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃ˜Đ° ĐżĐŸŃ€ŃƒĐșа за ĐŸĐ±Đ° ћасĐșања ŃĐżĐŸŃ˜Đ”ĐœĐ° јД ĐŸĐČĐŽĐ”.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{conversationTitle} јД ĐČĐ»Đ°ŃĐœĐžĐș Đ±Ń€ĐŸŃ˜Đ° {phoneNumber}. ĐžĐ±ĐŸŃ˜Đ” стД Ń‡Đ»Đ°ĐœĐŸĐČĐž ĐłŃ€ŃƒĐżĐ” {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{conversationTitle} јД ĐČĐ»Đ°ŃĐœĐžĐș Đ±Ń€ĐŸŃ˜Đ° {phoneNumber}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ХлОчОца слОĐșĐ” Оз Ń†ĐžŃ‚ĐžŃ€Đ°ĐœĐ” ĐżĐŸŃ€ŃƒĐșĐ”", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1467,7 +1563,7 @@ "description": "Used on reset buttons" }, "icu:fileIconAlt": { - "messageformat": "Ikona fajla", + "messageformat": "ИĐșĐŸĐœĐ° Ń„Đ°Ń˜Đ»Đ°", "description": "Used in the media gallery documents tab to visually represent a file" }, "icu:installWelcome": { @@ -1585,10 +1681,6 @@ "messageformat": "ĐŸĐŸĐ·ĐŸĐČĐž ĐżĐŸĐœĐŸĐČĐŸ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Đ—Đ°ĐżĐŸŃ‡Đ”Ń‚Đž ĐżĐŸĐ·ĐžĐČ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ĐŸŃ€ĐžĐŽŃ€ŃƒĐ¶Đž сД ĐżĐŸĐ·ĐžĐČу", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ јД ОсĐșŃ™ŃƒŃ‡Đ”Đœ Đ·Đ±ĐŸĐł ĐČĐ”Đ»ĐžŃ‡ĐžĐœĐ” ĐżĐŸĐ·ĐžĐČа", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ОбаĐČĐ”ŃˆŃ‚Đ”ŃšĐ° ĐŸ ĐżĐŸĐ·ĐžĐČĐžĐŒĐ°", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ĐŸĐŸĐ·ĐžĐČ Ń˜Đ” ĐżŃƒĐœ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ĐŸŃ€ĐžĐŽŃ€ŃƒĐ¶ĐžŃ‚Đ” сД", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Đ—Đ°ĐżĐŸŃ‡ĐœĐž", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ĐŸĐŸĐ·ĐžĐČ Ń˜Đ” ĐżŃƒĐœ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ° ОсĐșŃ™ŃƒŃ‡Đ”ĐœĐ°", @@ -1621,10 +1725,6 @@ "messageformat": "УпалО ĐșĐ°ĐŒĐ”Ń€Ńƒ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ИсĐșључо ĐŸĐ±Đ°ĐČĐ”ŃˆŃ‚Đ”ŃšĐ°", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ ОсĐșŃ™ŃƒŃ‡Đ”Đœ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ĐŁĐșључо ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ĐŸĐŸĐŽĐ”Đ»ĐžŃ‚Đ”", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ĐŸŃ€Đ”Đ·Đ”ĐœŃ‚Đ°Ń†ĐžŃ˜Đ° ĐŸĐœĐ”ĐŒĐŸĐłŃƒŃ›Đ”ĐœĐ°", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ЗаустаĐČљањД ĐżŃ€Đ”Đ·Đ”ĐœŃ‚Đ°Ń†ĐžŃ˜Đ”", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ЗĐČĐŸĐœĐž", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Група јД прДĐČДлОĐșа Ўа бО ĐżĐŸĐ·ĐČала ŃƒŃ‡Đ”ŃĐœĐžĐșĐ”.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "УпалО Đ·ĐČĐŸĐœĐŸ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "ИсĐșључо Đ·ĐČĐŸĐœĐŸ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ĐŁĐșључо Đ·ĐČĐŸĐœĐŸ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Đ’ĐžŃˆĐ” ĐŸĐżŃ†ĐžŃ˜Đ°", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Во", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Ваша ĐșĐ°ĐŒĐ”Ń€Đ° јД ОсĐșŃ™ŃƒŃ‡Đ”ĐœĐ°", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ПроĐșажО ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ĐŸĐŸŃ€ŃƒĐșа", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ПроĐșажО ŃĐžĐłŃƒŃ€ĐœĐŸŃĐœĐž Đ±Ń€ĐŸŃ˜", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ĐĐžŃ˜Đ” ĐŒĐŸĐłŃƒŃ›Đ” ĐœĐ°Đ»Đ°Đ·ĐžŃ‚Đž Đ±Ń€ĐŸŃ˜ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ°. ĐŸŃ€ĐŸĐČДрОтД Ўа лО стД ĐżĐŸĐČĐ”Đ·Đ°ĐœĐž ĐœĐ° ĐžĐœŃ‚Đ”Ń€ĐœĐ”Ń‚ Đž ĐżĐŸĐșŃƒŃˆĐ°Ń˜Ń‚Đ” ĐżĐŸĐœĐŸĐČĐŸ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ” сД ĐŒĐŸĐłŃƒ ĐżŃ€ĐžĐŒĐ”ĐœĐžŃ‚Đž ŃĐ°ĐŒĐŸ у Ń€ĐŸĐșу ĐŸĐŽ 3 сата ĐŸĐŽ Ń‚Ń€Đ”ĐœŃƒŃ‚Đșа ĐșаЎа стД ĐżĐŸŃĐ»Đ°Đ»Đž ĐŸĐČу ĐżĐŸŃ€ŃƒĐșу.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ” сД ĐŒĐŸĐłŃƒ ĐżŃ€ĐžĐŒĐ”ĐœĐžŃ‚Đž ŃĐ°ĐŒĐŸ у Ń€ĐŸĐșу ĐŸĐŽ 24 сата ĐŸĐŽ Ń‚Ń€Đ”ĐœŃƒŃ‚Đșа ĐșаЎа стД ĐżĐŸŃĐ»Đ°Đ»Đž ĐŸĐČу ĐżĐŸŃ€ŃƒĐșу.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2449,7 +2565,7 @@ "description": "Shown in notifications and in the left pane when an audio message is received." }, "icu:message--getNotificationText--file": { - "messageformat": "Fajl", + "messageformat": "Ѐајл", "description": "Shown in notifications and in the left pane when a generic file is received." }, "icu:message--getNotificationText--stickers": { @@ -2480,6 +2596,14 @@ "messageformat": "ОĐČа ĐżĐŸŃ€ŃƒĐșа јД ĐžĐ·Đ±Ń€ĐžŃĐ°ĐœĐ°.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ĐŸŃ€ĐžĐ»ĐŸĐł јД прДĐČДлОĐș Ўа бО ĐŒĐŸĐłĐ°ĐŸ Ўа буЎД проĐșĐ°Đ·Đ°Đœ.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ĐĐ”ĐșĐž ĐżŃ€ĐžĐ»ĐŸĐ·Đž су прДĐČДлОĐșĐž Ўа бО ĐŒĐŸĐłĐ»Đž Ўа буЎу проĐșĐ°Đ·Đ°ĐœĐž.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ĐĐžŃĐŒĐŸ успДлО Ўа ĐżŃ€Đ”ŃƒĐ·ĐŒĐ”ĐŒĐŸ ЎДтаљД ĐŸ ĐŽĐŸĐœĐ°Ń†ĐžŃ˜Đž", "description": "Aria label for donation when we can't fetch the details." @@ -2933,7 +3057,7 @@ "description": "Shown in the shortcuts guide" }, "icu:Keyboard--attach-file": { - "messageformat": "Zakači fajl", + "messageformat": "ЗаĐșачо Ń„Đ°Ń˜Đ»", "description": "Shown in the shortcuts guide" }, "icu:Keyboard--remove-draft-link-preview": { @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ĐĄĐ°ĐŒĐŸ у бДта ĐČĐ”Ń€Đ·ĐžŃ˜Đž Signal-а", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐ° ĐżĐŸŃ€ŃƒĐșа јД ĐŽĐŸŃŃ‚ŃƒĐżĐœĐ° ŃĐ°ĐŒĐŸ бДта ĐșĐŸŃ€ĐžŃĐœĐžŃ†ĐžĐŒĐ° Signal-а. АĐșĐŸ ĐžĐ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€ŃƒĐșу, ĐŸĐœĐ° ћД бОтО ĐČоЮљоĐČа ŃĐ°ĐŒĐŸ Ń™ŃƒĐŽĐžĐŒĐ° ĐșĐŸŃ˜Đž су ĐœĐ° ĐœĐ°Ń˜ĐœĐŸĐČĐžŃ˜ĐŸŃ˜ бДта ĐČĐ”Ń€Đ·ĐžŃ˜Đž Signal-а.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€ŃƒĐșу", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "АĐșĐŸ ĐžĐ·ĐŒĐ”ĐœĐžŃ‚Đ” ĐżĐŸŃ€ŃƒĐșу, ĐŸĐœĐ° ћД бОтО ĐČоЮљоĐČа ŃĐ°ĐŒĐŸ Ń™ŃƒĐŽĐžĐŒĐ° ĐșĐŸŃ˜Đž су ĐœĐ° ĐœĐ°Ń˜ĐœĐŸĐČĐžŃ˜ĐžĐŒ ĐČĐ”Ń€Đ·ĐžŃ˜Đ°ĐŒĐ° Signal-а. ĐžĐœĐž ћД ĐŒĐŸŃ›Đž Ўа ĐČОЎД Ўа стД ĐžĐ·ĐŒĐ”ĐœĐžĐ»Đž ĐżĐŸŃ€ŃƒĐșу.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3245,7 +3377,7 @@ "description": "Shown as the body in the confirmation modal for deleting a private message request" }, "icu:MessageRequests--delete-group-confirm-title": { - "messageformat": "ĐžĐ±Ń€ĐžŃˆĐž Đž ĐœĐ°ĐżŃƒŃŃ‚Đž {title}?", + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž Đž ĐœĐ°ĐżŃƒŃŃ‚Đž {title}?", "description": "Shown as the title in the confirmation modal for deleting a group message request" }, "icu:MessageRequests--delete-direct": { @@ -3380,6 +3512,14 @@ "messageformat": "Đ”ĐŸĐ»Đ°Đ·ĐœĐž ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "ĐžĐŽĐ»Đ°Đ·ĐœĐž ĐłĐ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ĐžĐŽĐ»Đ°Đ·ĐœĐž ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ĐČас Đ·ĐŸĐČĐ”", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ĐŸĐŸĐœĐŸĐČĐŸ ĐżĐŸĐČĐ”Đ·ŃƒŃ˜Đ”ĐŒĐŸâ€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} ĐŸŃĐŸĐ±Đ°} other {Њох {count,number}}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Đ“Đ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Крај", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Напусто", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ јД ОсĐșŃ™ŃƒŃ‡Đ”Đœ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МоĐșŃ€ĐŸŃ„ĐŸĐœ јД уĐșŃ™ŃƒŃ‡Đ”Đœ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ЗĐČĐŸĐœĐŸ јД уĐșŃ™ŃƒŃ‡Đ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ЗĐČĐŸĐœĐŸ јД ОсĐșŃ™ŃƒŃ‡Đ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐŸĐŸĐŽĐ”ŃˆĐ°ĐČања", @@ -3468,13 +3668,25 @@ "messageformat": "ĐŸĐŸĐ·ĐžĐČ Ńƒ ĐżŃƒĐœĐŸĐŒ Đ”ĐșŃ€Đ°ĐœŃƒ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐŸŃ€Đ”Ń’Đž ĐœĐ° проĐșаз ĐŒŃ€Đ”Đ¶Đ”", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ĐŸŃ€ĐŸĐŒĐ”ĐœĐž проĐșаз", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ĐŸŃ€Đ”Ń’Đž ĐœĐ° проĐșаз Đ·ĐČŃƒŃ‡ĐœĐžĐșа", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ĐœŃ€Đ”Đ¶Đ°", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Đ‘ĐŸŃ‡ĐœĐ° траĐșа", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ПроĐșаз ĐșĐŸŃ€ĐžŃĐœĐžĐșа", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ПроĐșаз јД Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°Đœ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Напусто ĐżĐŸĐ·ĐžĐČ", @@ -3576,6 +3788,14 @@ "messageformat": "ĐŁ Ń€Đ”ĐŽŃƒ", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ĐĐžŃ˜Đ” ĐŒĐŸĐłŃƒŃ›Đ” ĐžĐ·ĐŒĐ”ĐœĐžŃ‚Đž ĐżĐŸŃ€ŃƒĐșу", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Đ‘Ń€ĐŸŃ˜ ĐžĐ·ĐŒĐ”ĐœĐ° ĐșĐŸŃ˜Đ” сД ĐŒĐŸĐłŃƒ ŃƒĐœĐ”Ń‚Đž у ĐŸĐČу ĐżĐŸŃ€ŃƒĐșу: {max,number}.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ĐĐ°Đ¶Đ°Đ»ĐŸŃŃ‚ ĐŸĐČа sgnl:// ĐČДза ĐœĐ”ĐŒĐ° ŃĐŒĐžŃĐ»Đ°!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -3593,7 +3813,7 @@ "description": "Shown if we are unable to parse a group link" }, "icu:GroupV2--join--invalid-link": { - "messageformat": "Ovaj link za grupu nije ispravan. Proverite da li je ceo link kompletan i ispravan pre nego ĆĄto pokuĆĄate da se pridruĆŸite.", + "messageformat": "ОĐČај Đ»ĐžĐœĐș за групу ĐœĐžŃ˜Đ” оспраĐČĐ°Đœ. ĐŸŃ€ĐŸĐČДрОтД Ўа лО јД Ń†Đ”ĐŸ Đ»ĐžĐœĐș ĐșĐŸĐŒĐżĐ»Đ”Ń‚Đ°Đœ Đž оспраĐČĐ°Đœ прД ĐœĐ”ĐłĐŸ ŃˆŃ‚ĐŸ ĐżĐŸĐșŃƒŃˆĐ°Ń‚Đ” Ўа сД ĐżŃ€ĐžĐŽŃ€ŃƒĐ¶ĐžŃ‚Đ”.", "description": "Shown if we are unable to parse a group link" }, "icu:GroupV2--join--prompt": { @@ -3621,7 +3841,7 @@ "description": "Shown if you click a group link and we can't get information about it" }, "icu:GroupV2--join--link-revoked": { - "messageformat": "Link za grupu viĆĄe nije ispravan.", + "messageformat": "Đ›ĐžĐœĐș за групу ĐČОшД ĐœĐžŃ˜Đ” оспраĐČĐ°Đœ.", "description": "Shown if you click a group link and we can't get information about it" }, "icu:GroupV2--join--link-forbidden--title": { @@ -3801,27 +4021,27 @@ "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--disabled--you": { - "messageformat": "Isključili ste obavezno odobrenje administratora za link za grupu.", + "messageformat": "ИсĐșŃ™ŃƒŃ‡ĐžĐ»Đž стД ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ” Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ° за Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--disabled--other": { - "messageformat": "{adminName} je isključio/la obavezno odobrenje administratora za link za grupu.", + "messageformat": "{adminName} јД ОсĐșŃ™ŃƒŃ‡ĐžĐŸ/ла ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ” Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ° за Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--disabled--unknown": { - "messageformat": "Isključeno je obavezno odobrenje administratora za link za grupu.", + "messageformat": "ИсĐșŃ™ŃƒŃ‡Đ”ĐœĐŸ јД ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ” Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ° за Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--enabled--you": { - "messageformat": "Uključili ste obavezno odobrenje administratora za link za grupu.", + "messageformat": "ĐŁĐșŃ™ŃƒŃ‡ĐžĐ»Đž стД ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ” Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ° за Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--enabled--other": { - "messageformat": "{adminName} je uključio/la obavezno odobrenje administratora za link za grupu.", + "messageformat": "{adminName} јД уĐșŃ™ŃƒŃ‡ĐžĐŸ/ла ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ” Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ° за Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--access-invite-link--enabled--unknown": { - "messageformat": "Uključeno je obavezno odobrenje administratora za link za grupu.", + "messageformat": "ĐŁĐșŃ™ŃƒŃ‡Đ”ĐœĐŸ јД ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ” Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ° за Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--member-add--invited--you": { @@ -4141,51 +4361,51 @@ "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--disabled--you": { - "messageformat": "Uključili ste link za grupu bez obaveznog odobrenja administratora.", + "messageformat": "ĐŁĐșŃ™ŃƒŃ‡ĐžĐ»Đž стД Đ»ĐžĐœĐș за групу бДз ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸĐł ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ° Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--disabled--other": { - "messageformat": "{adminName} je uključio/la link za grupu bez obaveznog odobrenja administratora.", + "messageformat": "{adminName} јД уĐșŃ™ŃƒŃ‡ĐžĐŸ/ла Đ»ĐžĐœĐș за групу бДз ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸĐł ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ° Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--disabled--unknown": { - "messageformat": "Uključen je link za grupu bez obaveznog odobrenja administratora.", + "messageformat": "ĐŁĐșŃ™ŃƒŃ‡Đ”Đœ јД Đ»ĐžĐœĐș за групу бДз ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐŸĐł ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ° Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--enabled--you": { - "messageformat": "Uključili ste link za grupu sa obaveznim odobrenjem administratora.", + "messageformat": "ĐŁĐșŃ™ŃƒŃ‡ĐžĐ»Đž стД Đ»ĐžĐœĐș за групу са ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐžĐŒ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ”ĐŒ Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--enabled--other": { - "messageformat": "{adminName} je uključio/la link za grupu sa obaveznim odobrenjem administratora.", + "messageformat": "{adminName} јД уĐșŃ™ŃƒŃ‡ĐžĐŸ/ла Đ»ĐžĐœĐș за групу са ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐžĐŒ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ”ĐŒ Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-add--enabled--unknown": { - "messageformat": "Uključen je link za grupu sa obaveznim odobrenjem administratora.", + "messageformat": "ĐŁĐșŃ™ŃƒŃ‡Đ”Đœ јД Đ»ĐžĐœĐș за групу са ĐŸĐ±Đ°ĐČĐ”Đ·ĐœĐžĐŒ ĐŸĐŽĐŸĐ±Ń€Đ”ŃšĐ”ĐŒ Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-remove--you": { - "messageformat": "Isključili ste link za grupu.", + "messageformat": "ИсĐșŃ™ŃƒŃ‡ĐžĐ»Đž стД Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-remove--other": { - "messageformat": "{adminName} je isključio/la link za grupu.", + "messageformat": "{adminName} јД ОсĐșŃ™ŃƒŃ‡ĐžĐŸ/ла Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-remove--unknown": { - "messageformat": "Link za grupu je isključen.", + "messageformat": "Đ›ĐžĐœĐș за групу јД ОсĐșŃ™ŃƒŃ‡Đ”Đœ.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-reset--you": { - "messageformat": "Resetovali ste link za grupu.", + "messageformat": "Đ Đ”ŃĐ”Ń‚ĐŸĐČалО стД Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-reset--other": { - "messageformat": "{adminName} je resetovao/la link za grupu.", + "messageformat": "{adminName} јД Ń€Đ”ŃĐ”Ń‚ĐŸĐČĐ°ĐŸ/ла Đ»ĐžĐœĐș за групу.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-reset--unknown": { - "messageformat": "Link za grupu je resetovan.", + "messageformat": "Đ›ĐžĐœĐș за групу јД Ń€Đ”ŃĐ”Ń‚ĐŸĐČĐ°Đœ.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--description--remove--you": { @@ -4365,7 +4585,7 @@ "description": "Aria label for expanding composition area" }, "icu:CompositionArea--attach-file": { - "messageformat": "Zakači fajl", + "messageformat": "ЗаĐșачо Ń„Đ°Ń˜Đ»", "description": "Aria label for file attachment button in composition area" }, "icu:CompositionArea--sms-only__title": { @@ -4441,7 +4661,7 @@ "description": "Title for the modal to unmute a chat" }, "icu:ConversationDetails--group-link": { - "messageformat": "Link za grupu", + "messageformat": "Đ›ĐžĐœĐș за групу", "description": "This is the label for the group link management panel" }, "icu:ConversationDetails--disappearing-messages-label": { @@ -4597,7 +4817,7 @@ "description": "In the conversation notifications settings, this is the option that doesn't notify you for @mentions if the conversation is muted" }, "icu:GroupLinkManagement--clipboard": { - "messageformat": "Link za grupu je kopiran.", + "messageformat": "Đ›ĐžĐœĐș за групу јД ĐșĐŸĐżĐžŃ€Đ°Đœ.", "description": "Shown in a toast when a user selects to copy group link" }, "icu:GroupLinkManagement--share": { @@ -4605,11 +4825,11 @@ "description": "This lets users share their group link" }, "icu:GroupLinkManagement--confirm-reset": { - "messageformat": "Da li ste sigurni da ĆŸelite da resetujete link za grupu? Ljudi viĆĄe neće moći da se pridruĆŸe grupi preko trenutnog linka.", + "messageformat": "Да лО стД ŃĐžĐłŃƒŃ€ĐœĐž Ўа жДлОтД Ўа Ń€Đ”ŃĐ”Ń‚ŃƒŃ˜Đ”Ń‚Đ” Đ»ĐžĐœĐș за групу? ЉуЮо ĐČОшД ĐœĐ”Ń›Đ” ĐŒĐŸŃ›Đž Ўа сД ĐżŃ€ĐžĐŽŃ€ŃƒĐ¶Đ” групо прДĐșĐŸ Ń‚Ń€Đ”ĐœŃƒŃ‚ĐœĐŸĐł Đ»ĐžĐœĐșа.", "description": "Shown in the confirmation dialog when an admin is about to reset the group link" }, "icu:GroupLinkManagement--reset": { - "messageformat": "Resetuj link", + "messageformat": "Đ Đ”ŃĐ”Ń‚Ńƒj Đ»ĐžĐœĐș", "description": "This lets users generate a new group link" }, "icu:GroupLinkManagement--approve-label": { @@ -4617,7 +4837,7 @@ "description": "Title for the approve new members select area" }, "icu:GroupLinkManagement--approve-info": { - "messageformat": "Obavezno je da administrator odobri nove članove koji se pridruĆŸuju preko linka za grupu.", + "messageformat": "ОбаĐČĐ”Đ·ĐœĐŸ јД Ўа Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€ ĐłŃ€ŃƒĐżĐ” ĐŸĐŽĐŸĐ±Ń€Đž ĐœĐŸĐČĐ” Ń‡Đ»Đ°ĐœĐŸĐČĐ” ĐșĐŸŃ˜Đž сД ĐżŃ€ĐžĐŽŃ€ŃƒĐ¶ŃƒŃ˜Ńƒ групо прДĐșĐŸ Đ»ĐžĐœĐșа за групу.", "description": "Description for the approve new members select area" }, "icu:PendingInvites--tab-requests": { @@ -5113,7 +5333,7 @@ "description": "Text for an option in Disappearing Messages menu and Conversation Details Disappearing Messages setting when no user value is available" }, "icu:selectedCustomDisappearingTimeOption": { - "messageformat": "ĐŸŃ€ĐžĐ»Đ°ĐłĐŸĐŽĐžŃ‚Đž ĐČŃ€Đ”ĐŒĐ”", + "messageformat": "ĐŸŃ€ĐžĐ»Đ°ĐłĐŸŃ’Đ”ĐœĐŸ ĐČŃ€Đ”ĐŒĐ”", "description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time" }, "icu:DisappearingTimeDialog__label--value": { @@ -5125,7 +5345,7 @@ "description": "aria-label for the units of time select box" }, "icu:DisappearingTimeDialog__title": { - "messageformat": "ĐŸŃ€ĐžĐ»Đ°ĐłĐŸĐŽĐžŃ‚Đž ĐČŃ€Đ”ĐŒĐ”", + "messageformat": "ĐŸŃ€ĐžĐ»Đ°ĐłĐŸŃ’Đ”ĐœĐŸ ĐČŃ€Đ”ĐŒĐ”", "description": "Title for the custom disappearing message timeout dialog" }, "icu:DisappearingTimeDialog__body": { @@ -5252,10 +5472,30 @@ "messageformat": "ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ĐĐ”ŃˆŃ‚ĐŸ ĐœĐžŃ˜Đ” у Ń€Đ”ĐŽŃƒ са ĐČĐ°ŃˆĐžĐŒ ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐžĐŒ ĐžĐŒĐ”ĐœĐŸĐŒ – ĐČОшД ĐœĐžŃ˜Đ” ĐżĐŸĐČĐ”Đ·Đ°ĐœĐŸ са ĐČĐ°ŃˆĐžĐŒ ĐœĐ°Đ»ĐŸĐłĐŸĐŒ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ĐšŃ€Đ”ĐžŃ€Đ°Ń˜Ń‚Đ” ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ĐșĂŽĐŽ ОлО Đ»ĐžĐœĐș", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ” трДба Ń€Đ”ŃĐ”Ń‚ĐŸĐČато", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Đ›ĐžĐœĐș ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸĐł ĐžĐŒĐ”ĐœĐ° трДба Ń€Đ”ŃĐ”Ń‚ĐŸĐČато", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ĐŸĐŸĐŽĐ”Đ»ĐžŃ‚Đ” сĐČĐŸŃ˜Đ” ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ОĐČĐŸ ћД уĐșĐ»ĐŸĐœĐžŃ‚Đž ĐČашД ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ”, ĐŸĐŒĐŸĐłŃƒŃ›Đ°ĐČајућо ĐŽŃ€ŃƒĐłĐžĐŒ ĐșĐŸŃ€ĐžŃĐœĐžŃ†ĐžĐŒĐ° Ўа га захтДĐČају. ĐˆĐ”ŃŃ‚Đ” лО ŃĐžĐłŃƒŃ€ĐœĐž?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ОĐČĐžĐŒ ћДтД уĐșĐ»ĐŸĐœĐžŃ‚Đž ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ” Đž ĐŸĐœĐ”ĐŒĐŸĐłŃƒŃ›ĐžŃ‚Đž сĐČĐŸŃ˜ QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș. ĐšĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ” „{username}“ ћД бОтО ĐŽĐŸŃŃ‚ŃƒĐżĐœĐŸ ĐŽŃ€ŃƒĐłĐžĐŒĐ° за ĐżŃ€Đ”ŃƒĐ·ĐžĐŒĐ°ŃšĐ”. Да лО стД ŃĐžĐłŃƒŃ€ĐœĐž?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5481,7 +5717,7 @@ "description": "Label for changing the zoom level" }, "icu:Preferences__link-previews--title": { - "messageformat": "Generisanje prikaza linka", + "messageformat": "Đ“Đ”ĐœĐ”Ń€ĐžŃĐ°ŃšĐ” проĐșаза Đ»ĐžĐœĐșа", "description": "Title for the generate link previews setting" }, "icu:Preferences__link-previews--description": { @@ -5493,7 +5729,7 @@ "description": "Title for advanced settings" }, "icu:Preferences--notification-content": { - "messageformat": "ĐĄĐ°ĐŽŃ€Đ¶Đ°Ń˜ ĐœĐŸŃ‚ĐžŃ„ĐžĐșĐ°Ń†ĐžŃ˜Đ”", + "messageformat": "ĐĄĐ°ĐŽŃ€Đ¶Đ°Ń˜ ĐŸĐ±Đ°ĐČĐ”ŃˆŃ‚Đ”ŃšĐ°", "description": "Label for the notification content setting select box" }, "icu:Preferences--blocked": { @@ -5585,7 +5821,7 @@ "description": "Header for settings having to do with updates" }, "icu:Preferences__download-update": { - "messageformat": "ĐŃƒŃ‚ĐŸĐŒĐ°Ń‚ŃĐșĐŸ ĐżŃ€Đ”ŃƒĐ·Đ”Ń‚Đž Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°ŃšĐ°", + "messageformat": "ĐŃƒŃ‚ĐŸĐŒĐ°Ń‚ŃĐșĐŸ ĐżŃ€Đ”ŃƒĐ·ĐžĐŒĐ°ŃšĐ” Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°ŃšĐ°", "description": "Label for checkbox for the auto download updates setting" }, "icu:Preferences__enable-notifications": { @@ -5612,6 +5848,42 @@ "messageformat": "Đ’ĐžŃˆĐ” ĐœĐ”Ń›Đ”Ń‚Đ” ĐŒĐŸŃ›Đž Ўа ЎДлОтД ОлО ĐČОЎОтД прОчД. ĐĄĐČĐ” ŃˆŃ‚ĐŸ стД ĐœĐ”ĐŽĐ°ĐČĐœĐŸ ĐżĐŸĐŽĐ”Đ»ĐžĐ»Đž у ĐżŃ€ĐžŃ‡Đ°ĐŒĐ° ћД таĐșĐŸŃ’Đ” бОтО ĐžĐ·Đ±Ń€ĐžŃĐ°ĐœĐŸ.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ЈДзОĐș", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ЈДзОĐș", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ĐĄĐžŃŃ‚Đ”ĐŒŃĐșĐž јДзОĐș", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ĐŸŃ€Đ”Ń‚Ń€Đ°Đ¶Đž јДзОĐșĐ”", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ĐĐ”ĐŒĐ° Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đ° за „{searchTerm}“", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ĐŸĐŸŃŃ‚Đ°ĐČĐž", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ĐŸĐŸĐœĐŸĐČĐŸ ĐżĐŸĐșŃ€Đ”ĐœĐžŃ‚Đ” Signal Ўа ĐżŃ€ĐžĐŒĐ”ĐœĐžŃ‚Đ”", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Да бОстД ĐżŃ€ĐŸĐŒĐ”ĐœĐžĐ»Đž јДзОĐș, аплОĐșацоја ĐŒĐŸŃ€Đ° ĐżĐŸĐœĐŸĐČĐŸ Ўа сД ĐżĐŸĐșŃ€Đ”ĐœĐ”.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ĐŸĐŸĐșŃ€Đ”ĐœĐž ĐżĐŸĐœĐŸĐČĐŸ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Đ”ĐŸŃŃ‚ŃƒĐżĐœĐŸ Đ°Đ¶ŃƒŃ€ĐžŃ€Đ°ŃšĐ” ĐœĐ° ĐČĐ”Ń€Đ·ĐžŃ˜Đž {version}", "description": "Tooltip for new update available" @@ -5657,11 +5929,11 @@ "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" }, "icu:NSIS__decompressionFailed": { - "messageformat": "Dekomprimovanje fajlova nije uspelo. Probajte ponovo da pokrenete instalacioni program.", + "messageformat": "ДДĐșĐŸĐŒĐżŃ€ĐžĐŒĐŸĐČањД Ń„Đ°Ń˜Đ»ĐŸĐČа ĐœĐžŃ˜Đ” ŃƒŃĐżĐ”Đ»ĐŸ. ĐŸŃ€ĐŸĐ±Đ°Ń˜Ń‚Đ” ĐżĐŸĐœĐŸĐČĐŸ Ўа ĐżĐŸĐșŃ€Đ”ĐœĐ”Ń‚Đ” ĐžĐœŃŃ‚Đ°Đ»Đ°Ń†ĐžĐŸĐœĐž ĐżŃ€ĐŸĐłŃ€Đ°ĐŒ.", "description": "Displayed when Windows installer cannot decompress application files" }, "icu:NSIS__uninstallFailed": { - "messageformat": "Deinstaliranje starih fajlova aplikacije nije uspelo. Probajte ponovo da pokrenete instalacioni program.", + "messageformat": "Đ”Đ”ĐžĐœŃŃ‚Đ°Đ»ĐžŃ€Đ°ŃšĐ” старох Ń„Đ°Ń˜Đ»ĐŸĐČа ĐœĐžŃ˜Đ” ŃƒŃĐżĐ”Đ»ĐŸ. ĐŸŃ€ĐŸĐ±Đ°Ń˜Ń‚Đ” ĐżĐŸĐœĐŸĐČĐŸ Ўа ĐżĐŸĐșŃ€Đ”ĐœĐ”Ń‚Đ” ĐžĐœŃŃ‚Đ°Đ»Đ°Ń†ĐžĐŸĐœĐž ĐżŃ€ĐŸĐłŃ€Đ°ĐŒ.", "description": "Displayed when Windows installer cannot uninstall the old application" }, "icu:NSIS__semver-downgrade": { @@ -5696,6 +5968,10 @@ "messageformat": "Đ”ĐŸĐłĐŸĐŽĐžĐ»Đ° сД ĐłŃ€Đ”ŃˆĐșĐ” про сачуĐČаĐČањД ĐżĐŸĐŽĐ”ŃˆĐ°ĐČања. ĐŸĐŸĐœĐČото.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ĐŸĐŸŃ€ŃƒĐșа", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ĐˆĐŸŃˆ ŃŃ‚ĐžĐ»ĐŸĐČа", "description": "Action button for switching up the clock styles" @@ -5997,7 +6273,7 @@ "description": "Title for the who can see this story section" }, "icu:StoriesSettings__add-viewer": { - "messageformat": "Dodajte gledaoca", + "messageformat": "Đ”ĐŸĐŽĐ°Ń˜Ń‚Đ” ĐłĐ»Đ”ĐŽĐ°ĐŸŃ†Đ°", "description": "Button label to add a viewer to a story" }, "icu:StoriesSettings__remove--action": { @@ -6033,7 +6309,7 @@ "description": "Confirmation text to delete a custom distribution list" }, "icu:StoriesSettings__choose-viewers": { - "messageformat": "Izaberite gledaoce", + "messageformat": "Đ˜Đ·Đ°Đ±Đ”Ń€ĐžŃ‚Đ” ĐłĐ»Đ”ĐŽĐ°ĐŸŃ†Đ”", "description": "Modal title when choosing to add a viewer to a custom distribution list" }, "icu:StoriesSettings__name-story": { @@ -6261,7 +6537,7 @@ "description": "Sent timestamp" }, "icu:StoryDetailsModal__file-size": { - "messageformat": "Veličina fajla {size}", + "messageformat": "Đ’Đ”Đ»ĐžŃ‡ĐžĐœĐ° Ń„Đ°Ń˜Đ»Đ° {size}", "description": "File size description" }, "icu:StoryDetailsModal__disappears-in": { @@ -6532,6 +6808,10 @@ "messageformat": "Đ Đ”ŃĐ”Ń‚ŃƒŃ˜", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Đ“ĐŸŃ‚ĐŸĐČĐŸ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Đ‘ĐŸŃ˜Đ° Đ»ĐžĐœĐșа ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸĐł ĐžĐŒĐ”ĐœĐ°, {index,number} ĐŸĐŽ {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "АĐșĐŸ Ń€Đ”ŃĐ”Ń‚ŃƒŃ˜Đ”Ń‚Đ” QR ĐșĐŸĐŽ, ĐČашО ĐżĐŸŃŃ‚ĐŸŃ˜Đ”Ń›Đž QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș ĐČОшД ĐœĐ”Ń›Đ” раЮото.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Đ Đ”ŃĐ”Ń‚ŃƒŃ˜Đ”ĐŒĐŸ Đ»ĐžĐœĐș
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR ĐșĐŸĐŽ Đž Đ»ĐžĐœĐș ĐœĐžŃŃƒ ĐżĐŸĐŽĐ”ŃˆĐ”ĐœĐž. ĐŸŃ€ĐŸĐČДрОтД Ўа лО стД ĐżĐŸĐČĐ”Đ·Đ°ĐœĐž ĐœĐ° ĐŒŃ€Đ”Đ¶Ńƒ Đž ĐżŃ€ĐŸĐ±Đ°Ń˜Ń‚Đ” ĐżĐŸĐœĐŸĐČĐŸ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "ĐŸĐŸĐŽĐ”ŃĐžŃ‚Đ” ĐșĐŸŃ€ĐžŃĐœĐžŃ‡ĐșĐŸ ĐžĐŒĐ” за Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "ĐžĐ·ĐŒĐ”ŃšĐ”ĐœĐŸ", + "messageformat": "Đ˜Đ·ĐŒĐ”ŃšĐ”ĐœĐŸ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ĐŸĐŸŃˆĐ°Ń™Đž ĐżĐŸĐœĐŸĐČĐŸ", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Đ’ĐžŃˆĐ” аĐșцоја", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ĐŸĐŸĐ·ĐžĐČĐž", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ĐĐŸĐČĐž ĐżĐŸĐ·ĐžĐČ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ĐĐŸĐČĐž ĐżĐŸĐ·ĐžĐČ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Đ’ĐžŃˆĐ” аĐșцоја", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Đ˜Đ·Đ±Ń€ĐžŃˆĐž ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Ńƒ ĐżĐŸĐ·ĐžĐČа", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "ЖДлОтД лО Ўа ĐžĐ·Đ±Ń€ĐžŃˆĐ”Ń‚Đ” ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Ńƒ ĐżĐŸĐ·ĐžĐČа?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ОĐČĐžĐŒ ћДтД Ń‚Ń€Đ°Ń˜ĐœĐŸ ОзбрОсатО Ń†Đ”Đ»ĐŸĐșŃƒĐżĐœŃƒ ĐžŃŃ‚ĐŸŃ€ĐžŃ˜Ńƒ ĐżĐŸĐ·ĐžĐČа", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Очостото", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Đ˜ŃŃ‚ĐŸŃ€ĐžŃ˜Đ° ĐżĐŸĐ·ĐžĐČа јД ĐžĐ·Đ±Ń€ĐžŃĐ°ĐœĐ°", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "КлОĐșĐœĐžŃ‚Đ” за проĐșаз ОлО Ўа Đ·Đ°ĐżĐŸŃ‡ĐœĐ”Ń‚Đ” ĐżĐŸĐ·ĐžĐČ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "йражО", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Đ€ĐžĐ»Ń‚Ń€ĐžŃ€Đ°Ń˜ ĐżŃ€Đ”ĐŒĐ° ĐżŃ€ĐŸĐżŃƒŃˆŃ‚Đ”ĐœĐžĐŒ ĐżĐŸĐ·ĐžĐČĐžĐŒĐ°", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ĐŸŃ€Đ”Đ±Đ°Ń†Đž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĐĐ”ĐŒĐ° ĐœĐ”ĐŽĐ°ĐČĐœĐžŃ… ĐżĐŸĐ·ĐžĐČа. Đ—Đ°ĐżĐŸŃ‡ĐœĐžŃ‚Đ” таĐșĐŸ ŃˆŃ‚ĐŸ ћДтД ĐżĐŸĐ·ĐČато ĐżŃ€ĐžŃ˜Đ°Ń‚Đ”Ń™Đ°.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ĐĐ”ĐŒĐ° Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đ° за „{query}“", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Đ”ĐŸĐ»Đ°Đ·ĐœĐž ĐżĐŸĐ·ĐžĐČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ĐžĐŽĐ»Đ°Đ·ĐœĐž", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”ĐœĐž", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Đ“Ń€ŃƒĐżĐœĐž ĐżĐŸĐ·ĐžĐČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĐĐ”ĐŒĐ° ĐœĐ”ĐŽĐ°ĐČĐœĐžŃ… прДпОсĐșĐž.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ĐĐ”ĐŒĐ° Ń€Đ”Đ·ŃƒĐ»Ń‚Đ°Ń‚Đ° за „{query}“", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {ĐžĐŽĐ»Đ°Đ·ĐœĐž ĐłĐ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ} other {Đ”ĐŸĐ»Đ°Đ·ĐœĐž ĐłĐ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ}}} Video {{direction, select, Outgoing {ĐžĐŽĐ»Đ°Đ·ĐœĐž ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ} other {Đ”ĐŸĐ»Đ°Đ·ĐœĐž ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ}}} Group {{direction, select, Outgoing {ĐžĐŽĐ»Đ°Đ·ĐœĐž ĐłŃ€ŃƒĐżĐœĐž ĐżĐŸĐ·ĐžĐČ} other {Đ”ĐŸĐ»Đ°Đ·ĐœĐž ĐłŃ€ŃƒĐżĐœĐž ĐżĐŸĐ·ĐžĐČ}}} other {{direction, select, Outgoing {ĐžĐŽĐ»Đ°Đ·ĐœĐž ĐżĐŸĐ·ĐžĐČ} other {Đ”ĐŸĐ»Đ°Đ·ĐœĐž ĐżĐŸĐ·ĐžĐČ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ} Video {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ} Group {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐłŃ€ŃƒĐżĐœĐž ĐżĐŸĐ·ĐžĐČ} other {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐżĐŸĐ·ĐžĐČ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ĐĐ”ĐŸĐŽĐłĐŸĐČĐŸŃ€Đ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ} Video {ĐŸŃ€ĐŸĐżŃƒŃˆŃ‚Đ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ} Group {ĐĐ”ĐŸĐŽĐłĐŸĐČĐŸŃ€Đ”Đœ ĐłŃ€ŃƒĐżĐœĐž ĐżĐŸĐ·ĐžĐČ} other {ĐĐ”ĐŸĐŽĐłĐŸĐČĐŸŃ€Đ”Đœ ĐżĐŸĐ·ĐžĐČ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ĐžĐŽĐ±ĐžŃ˜Đ”Đœ ĐłĐ»Đ°ŃĐŸĐČĐœĐž ĐżĐŸĐ·ĐžĐČ} Video {ĐžĐŽĐ±ĐžŃ˜Đ”Đœ ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČ} Group {ĐžĐŽĐ±ĐžŃ˜Đ”Đœ ĐłŃ€ŃƒĐżĐœĐž ĐżĐŸĐ·ĐžĐČ} other {ĐžĐŽĐ±ĐžŃ˜Đ”Đœ ĐżĐŸĐ·ĐžĐČ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {ĐˆĐŸŃˆ {count,number} ĐŸŃĐŸĐ±Đ° Đșуца.} other {ĐˆĐŸŃˆ њох {count,number} Đșуцају.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "йта ĐœĐŸĐČĐŸ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Obavili smo manja fina prilagođavanja, ispravke greĆĄaka i poboljĆĄanja performansi. Hvala ĆĄto koristite Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ОĐČа ĐČĐ”Ń€Đ·ĐžŃ˜Đ° саЎржО ĐœĐ”ĐșĐŸĐ»ĐžĐșĐŸ ĐœĐŸĐČĐžĐœĐ° у ĐČОЎу ĐżĐŸĐ±ĐŸŃ™ŃˆĐ°ĐœĐŸĐł ĐșĐČалОтДта ĐłĐ»Đ°ŃĐŸĐČĐœĐžŃ… Đž ĐČĐžĐŽĐ”ĐŸ ĐżĐŸĐ·ĐžĐČа Đž ĐœĐ”ĐșĐ” ĐŒĐ°ŃšĐ” ĐœĐŸĐČĐžĐœĐ” у ĐČДзО са ĐŽĐŸĐșŃƒĐŒĐ”ĐœŃ‚Đ°Ń†ĐžŃ˜ĐŸĐŒ (хĐČала, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "ХаЎа ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐżŃ€ĐŸĐŒĐ”ĐœĐžŃ‚Đ” ĐžĐ·Đ°Đ±Ń€Đ°ĐœĐž јДзОĐș у Signal-у бДз ĐżŃ€ĐŸĐŒĐ”ĐœĐ” ĐżĐŸĐŽĐ”ŃˆĐ°ĐČања ŃĐžŃŃ‚Đ”ĐŒĐ° (ĐŸĐŸĐŽĐ”ŃˆĐ°ĐČања Signal-а > ИзглДЎ > ЈДзОĐș)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Đ˜Đ·ĐŒĐ”ĐœĐžĐ»Đž ŃĐŒĐŸ ĐžĐșĐŸĐœĐ” за ĐŸĐ±Đ°ĐČĐ”ŃˆŃ‚Đ”ŃšĐ° ĐșĐŸŃ˜Đ” сД ĐżĐŸŃ˜Đ°ĐČљују за ĐœĐŸĐČĐŸŃŃ‚Đž у ĐłŃ€ŃƒĐżĐ°ĐŒĐ°." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ИспраĐČОлО ŃĐŒĐŸ ĐșратĐșĐŸ ĐșĐ°ŃˆŃšĐ”ŃšĐ” ĐșĐŸŃ˜Đ” сД ĐżĐŸĐœĐ”ĐșаЎ ЎДшаĐČĐ°Đ»ĐŸ ĐœĐ° ŃƒŃ€Đ”Ń’Đ°Ń˜ĐžĐŒĐ° macOS ĐœĐ°ĐșĐŸĐœ уласĐșа у Đ»ĐŸĐ±Đž за ĐżĐŸĐ·ĐžĐČĐ”." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ĐŸĐŸĐżŃ€Đ°ĐČОлО ŃĐŒĐŸ Đ°ĐœĐžĐŒĐ°Ń†ĐžŃ˜Ńƒ прДлаза ĐșĐŸĐŽ ĐČĐžĐŽĐ”ĐŸ ĐżĐ»ĐŸŃ‡ĐžŃ†Đ° ĐșаЎа сД ĐœĐ”ĐșĐŸ ĐżŃ€ĐžĐŽŃ€ŃƒĐ¶Đž ĐłŃ€ŃƒĐżĐœĐŸĐŒ ĐżĐŸĐ·ĐžĐČу ОлО га ĐœĐ°ĐżŃƒŃŃ‚Đž." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ХаЎа ĐŒĐŸĐ¶Đ”Ń‚Đ” Ўа ĐșлОĐșĐœĐ”Ń‚Đ” ĐœĐ° ĐżŃ€ĐŸŃ„ĐžĐ»ĐœŃƒ слОĐșу ОлО аĐČатар ĐłŃ€ŃƒĐżĐ” у заглаĐČљу ћасĐșања Ўа бОстД Đ±Ń€Đ·ĐŸ ĐżŃ€ĐžŃŃ‚ŃƒĐżĐžĐ»Đž ĐżĐŸĐŽĐ”ŃˆĐ°ĐČĐ°ŃšĐžĐŒĐ° ћасĐșања ОлО прДглДЎалО сĐČĐ” ĐœĐ”ĐżŃ€Đ”ĐłĐ»Đ”ĐŽĐ°ĐœĐ” прОчД Оз Ń‚ĐŸĐł ћасĐșања. Đ„ĐČала, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json index a791b837e7..d2a7814ec4 100644 --- a/_locales/sv/messages.json +++ b/_locales/sv/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Databasfel", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Ett databasfel intrĂ€ffade. Du kan kopiera felet och kontakta Signal-supporten för att hjĂ€lpa till att Ă„tgĂ€rda problemet. Om du behöver anvĂ€nda Signal pĂ„ en gĂ„ng kan du radera dina data och starta om.\n\nKontakta supporten genom att besöka: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Ta bort alla data och starta om", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Ta bort data och starta om", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Ta bort alla data permanent?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "All din meddelandehistorik och media kommer att tas bort permanent frĂ„n den hĂ€r enheten. Du kommer att kunna anvĂ€nda Signal pĂ„ den hĂ€r enheten efter att du har lĂ€nkat om den. Detta tar inte bort nĂ„gra data frĂ„n din telefon.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Versionen av din databas matchar inte den hĂ€r versionen av Signal. Se till att du öppnar den senaste versionen av Signal pĂ„ din dator.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Arkiv", @@ -300,6 +316,70 @@ "messageformat": "Chattar", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "NĂ„got gick fel med ditt anvĂ€ndarnamn. Det Ă€r inte lĂ€ngre tilldelat ditt konto. Du kan försöka stĂ€lla in det igen eller vĂ€lja ett nytt.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ÅtgĂ€rda nu", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "NĂ„got gick fel med QR-koden och lĂ€nken för ditt anvĂ€ndarnamn. De Ă€r inte lĂ€ngre giltiga. Skapa en ny lĂ€nk för att dela med andra.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ÅtgĂ€rda nu", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Visa flikar", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Dölj flikar", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ett fel intrĂ€ffade", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} olĂ€sta", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Markerad som olĂ€st", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chattar", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Samtal", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "InstĂ€llningar", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Uppdatera Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Tillbaka", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Dessa chattar Ă€r arkiverade och kommer bara visas i inkorgen ifall nya meddelanden tas emot.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ring Ă€ndĂ„", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "GĂ„ med Ă€ndĂ„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "FortsĂ€tt samtalet", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "SĂ€kerhetsnummer uppdateras.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "LĂ€s mer", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Tidigare sĂ€kerhetsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "NĂ€sta sĂ€kerhetsnummer", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "SĂ€kerhetsnummer version {index,number} av {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Markera som verifierat", @@ -663,33 +747,41 @@ "messageformat": "Rensa verifiering", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "För att verifiera totalstrĂ€ckskryptering med {name}, jĂ€mför siffrorna ovan med deras enhet. De kan ocksĂ„ skanna din kod med sin enhet.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "LĂ€s mer", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "För att verifiera totalstrĂ€ckskryptering med {name}, matcha fĂ€rgkortet ovan med deras enhet och jĂ€mför siffrorna. Om dessa inte matchar, prova det andra paret sĂ€kerhetsnummer. Endast ett par behöver matcha.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "För att verifiera totalstrĂ€ckskryptering med {name}, jĂ€mför siffrorna ovan med deras enhet. De kan ocksĂ„ skanna din kod med sin enhet.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Ändringar av sĂ€kerhetsnummer", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "SĂ€kerhetsnummer uppdateras under en övergĂ„ngsperiod för att möjliggöra kommande sekretessfunktioner i Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "För att verifiera sĂ€kerhetsnummer, matcha fĂ€rgkortet med din kontakts enhet. Om dessa inte matchar, prova det andra paret sĂ€kerhetsnummer. Endast ett par behöver matcha.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Behöver du hjĂ€lp?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Uppfattat", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Ett sĂ€kerhetsnummer kommer att skapas med den hĂ€r personen efter att ni skickar meddelanden till varandra.", @@ -1267,10 +1359,6 @@ "messageformat": "Visa senaste media", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "För att verifiera sĂ€kerheten för din totalstrĂ€ckskryptering med {name}, jĂ€mför siffrorna ovan med deras enhet. De kan ocksĂ„ skanna QR-koden ovan.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "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." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Ta bort", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Ta bort meddelanden", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Ta bort chatt?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Ta bort meddelanden?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Denna chatt kommer att tas bort frĂ„n denna enhet.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Meddelanden i den hĂ€r chatten kommer att tas bort frĂ„n den hĂ€r enheten. Du kan fortfarande söka efter den hĂ€r chatten nĂ€r du har tagit bort meddelanden.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "LĂ€mna grupp", @@ -1438,6 +1526,14 @@ "messageformat": "Din meddelandehistorik för bĂ„da chattarna har slagits samman hĂ€r.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} tillhör {conversationTitle}. Ni Ă€r bĂ„da medlemmar i {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} tillhör {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Miniatyr av bild för citerat meddelande", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ring igen", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Starta samtal", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "GĂ„ med i samtalet", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Mikrofonen Ă€r av pĂ„ grund av samtalets storlek", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Samtalsaviseringar", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Samtalet Ă€r fullt", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "GĂ„ med", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Starta", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Samtal Ă€r fullt", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kameran inaktiverad", @@ -1621,10 +1725,6 @@ "messageformat": "Aktivera kameran", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Tysta", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon inaktiverad", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "SlĂ„ pĂ„ mikrofonen", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Dela", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Presentation inaktiverad", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Sluta presentera", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ring", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Gruppen Ă€r för stor för att ringa deltagarna.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Aktivera ringning", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "StĂ€ng av ringsignal", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "SlĂ„ pĂ„ ringsignal", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Fler alternativ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Du", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Din kamera Ă€r avstĂ€ngd", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Visa sĂ€kerhetsnummer", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Meddelande", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Visa sĂ€kerhetsnummer", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "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" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Redigeringar kan bara tillĂ€mpas inom 3 timmar frĂ„n det att du skickade det hĂ€r meddelandet.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Redigeringar kan bara tillĂ€mpas inom 24 timmar frĂ„n det att du skickade det hĂ€r meddelandet.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Det hĂ€r meddelandet togs bort.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Bifogade filen Ă€r för stor för att visas.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Vissa bifogade filer Ă€r för stora för att visas.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Det gick inte att hĂ€mta information om donationen", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Endast Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Redigering av meddelanden Ă€r endast tillgĂ€ngligt för betaanvĂ€ndare av Signal. Om du redigerar ett meddelande kommer det bara att vara synligt för personer som anvĂ€nder den senaste betaversionen av Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Redigera meddelande", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Om du redigerar ett meddelande kommer det bara att vara synligt för personer som anvĂ€nder de senaste versionerna av Signal. De kommer att kunna se att du redigerade ett meddelande.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Inkommande videosamtal 
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "UtgĂ„ende röstsamtal", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "UtgĂ„ende videosamtal", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ringer dig", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Återansluter 
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} person} other {{count,number} personer}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Ljudsamtal", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Avsluta", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "LĂ€mna", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon av", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon pĂ„", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Ringsignal pĂ„", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Ringsignal av", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "InstĂ€llningar", @@ -3468,13 +3668,25 @@ "messageformat": "HelskĂ€rmssamtal", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Byt till rutnĂ€tsvy", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Ändra vy", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Byt till högtalarvy", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "RutnĂ€tsvy", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "SidofĂ€ltsvy", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Talarvy", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Vy uppdaterad", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "LĂ€mna samtalet", @@ -3576,6 +3788,14 @@ "messageformat": "Okej", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Det gĂ„r inte att redigera meddelande", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Endast {max,number} redigeringar kan tillĂ€mpas pĂ„ det hĂ€r meddelandet.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "TyvĂ€rr, sgnl://-lĂ€nken var inte meningsfull!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "AnvĂ€ndarnamn", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "NĂ„got gick fel med ditt anvĂ€ndarnamn. Det Ă€r inte lĂ€ngre tilldelat ditt konto.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Ta bort anvĂ€ndarnamn", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Skapa anvĂ€ndarnamn", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-kod eller lĂ€nk", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "AnvĂ€ndarnamnet behöver Ă„terstĂ€llas", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "AnvĂ€ndarnamnslĂ€nken behöver Ă„terstĂ€llas", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Dela ditt anvĂ€ndarnamn", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Ta bort anvĂ€ndarnamn", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Det hĂ€r kommer att ta bort ditt anvĂ€ndarnamn, vilket gör att andra anvĂ€ndare kan göra ansprĂ„k pĂ„ det. Är du sĂ€ker?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Detta tar bort ditt anvĂ€ndarnamn och inaktiverar din QR-kod och lĂ€nk. \"{username}\" kommer att kunna vĂ€ljas av andra. Är du sĂ€ker?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Du kommer inte lĂ€ngre att kunna dela eller visa berĂ€ttelser. BerĂ€ttelseuppdateringar som du nyligen har delat kommer ocksĂ„ att raderas.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "SprĂ„k", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "SprĂ„k", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "SystemsprĂ„k", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Sök sprĂ„k", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Inga resultat för ”{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "StĂ€ll in", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Starta om Signal för att tillĂ€mpa", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Appen mĂ„ste startas om för att Ă€ndra sprĂ„k.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Starta om", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Uppdatering till version {version} tillgĂ€nglig", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Det uppstod ett fel nĂ€r du sparade dina instĂ€llningar. Försök igen.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Meddelande", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Fler stilar", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ÅterstĂ€ll", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Klar", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "LĂ€nkfĂ€rg för anvĂ€ndarnamn, {index,number} av {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Om du Ă„terstĂ€ller din QR-kod kommer din befintliga QR-kod och lĂ€nk inte lĂ€ngre att fungera.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ÅterstĂ€ller lĂ€nk 
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-kod och lĂ€nk inte instĂ€llda. Kontrollera nĂ€tverksanslutningen och försök igen.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "StĂ€ll in ditt Signal-anvĂ€ndarnamn", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "redigerad", + "messageformat": "Redigerad", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Skicka igen", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Fler Ă„tgĂ€rder", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Samtal", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Nytt samtal", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Nytt samtal", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Fler Ă„tgĂ€rder", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Rensa samtalshistorik", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Rensa samtalshistorik?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Detta kommer att radera all samtalshistorik permanent", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Rensa", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Samtalshistoriken rensad", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Klicka för att visa eller starta ett samtal", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Sök", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Filtrera efter missade", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "VĂ€xla", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Inga nyliga samtal. Kom igĂ„ng genom att ringa en vĂ€n.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Inga resultat för ”{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Inkommande", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "UtgĂ„ende", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Missat", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Gruppsamtal", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Inga senaste konversationer.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Inga resultat för ”{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {UtgĂ„ende röstsamtal} other {Inkommande röstsamtal}}} Video {{direction, select, Outgoing {UtgĂ„ende videosamtal} other {Inkommande videosamtal}}} Group {{direction, select, Outgoing {UtgĂ„ende gruppsamtal} other {Inkommande gruppsamtal}}} other {{direction, select, Outgoing {UtgĂ„ende samtal} other {Inkommande samtal}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Missat röstsamtal} Video {Missat videosamtal} Group {Missat gruppsamtal} other {Missat samtal}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Obesvarat röstsamtal} Video {Obesvarat videosamtal} Group {Obesvarat gruppsamtal} other {Obesvarat samtal}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Avvisat röstsamtal} Video {Avvisat videosamtal} Group {Avvisat gruppsamtal} other {Avvisat samtal}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} annan skriver.} other {{count,number} andra skriver.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Vad Ă€r nytt", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "SmĂ„ justeringer, buggfixar och prestandaförbĂ€ttringar. Tack för att du anvĂ€nder Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Den hĂ€r uppdateringen innehĂ„ller förbĂ€ttringar för röst- och videosamtal och nĂ„gra mindre dokumentationsuppdateringar (tack {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Nu kan du Ă€ndra ditt valda sprĂ„k i Signal utan att Ă€ndra dina systeminstĂ€llningar (Signal-instĂ€llningar > Utseende > SprĂ„k)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Vi uppdaterade nĂ„gra aviseringsikoner för grupper." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Vi Ă„tgĂ€rdade en kort fördröjning som ibland uppstod i macOS efter att man gĂ„tt med i en samtalslobby." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Vi har Ă„tgĂ€rdat övergĂ„ngsanimationen för videobrickor nĂ€r nĂ„gon gĂ„r med i eller lĂ€mnar ett gruppsamtal." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Nu kan du klicka pĂ„ en profilbild eller gruppavatar i chattrubriken för att snabbt komma Ă„t chattinstĂ€llningar eller visa ovisade berĂ€ttelser frĂ„n den chatten. Tack @!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/sw/messages.json b/_locales/sw/messages.json index 097fcef6a9..dfec60e476 100644 --- a/_locales/sw/messages.json +++ b/_locales/sw/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Hitilafu ya hifadhidata", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Hitilafu ya kanzidata imetokea. Unaweza kunakili tatizo na kuwasiliana na watoa huduma wa Signal ili kukusaidia kurekebisha tatizo. Ikiwa unahitaji kutumia Signal haraka sana, unaweza kufuta data yako na kuanza upya. \n\nWasiliana na watoa huduma kwa kutembelea: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Futa data yote na washa upya", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Futa data na anza upya", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Je, unataka kufuta data yote daima?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Historia yote ya jumbe na media zako zitafutwa daima kwenye kifaa hiki. Utaweza kutumia Signal kwenye kifaa hiki baada ya kukiunganisha upya. Hii haitafuta data yoyote kwenye simu yako.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Toleo hili la kanzidata halilingani na toleo la Signal. Hakikisha unafungua toleo jipya zaidi la Signal kwenye kompyuta yako.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Faili", @@ -300,6 +316,70 @@ "messageformat": "Gumzo", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Kuna tatizo limetokea kwenye jina lako la mtumiaji, halijaandikishwa tena katika akaunti yako. Unaweza kujaribu na kuweka upya au unaweza kuchagua jingine.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Rekebisha sasa", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Kuna tatizo limetokea kwenye msimbo wako wa QR na kiungo cha jina lako la mtumiaji, sio halali tena. Tengeneza kiungo kipya ili ushiriki na wengine.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Rekebisha sasa", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Onyesha Vichupo", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Ficha Vichupo", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Hitilafu imetokea", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} hazijasomwa", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Imetiwa alama haijasomwa", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Gumzo", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Simu", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stori", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Mipangilio", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Sasisha Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Wasifa", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Rudi nyuma", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Gumzo hizi zimehifadhiwa na zitaonekana tu kwenye Kikasha ikiwa ujumbe mpya utapokelewa.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Piga simu tu", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Jiunge hata hivyo", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Endelea na Mazungumzo ya Simu", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Nambari za usalama zinasasishwa.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Jifunze zaidi", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Nambari ya Usalama Iliyotangulia", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Nambari ya Usalama Inayofuata", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Toleo la nambari ya usalama, {index,number} ya {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Weka alama kuwa imehakikishwa", @@ -663,33 +747,41 @@ "messageformat": "Futa uthibitishwaji", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Ili kuthibitisha usimbaji fiche wa mwanzo hadi mwisho na {name}, linganisha nambari zilizo hapo juu na kifaa chao. Pia, wanaweza kupiga skani msimbo wako na kifaa chao.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Jifunze zaidi", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Ili kuthibitisha usimbaji fiche wa mwanzo hadi mwisho na {name}, fananisha kadi ya rangi iliyo hapo juu na kifaa chake na ulinganishe nambari. Kama hivi havilingani, jaribu jozi nyingine ya nambari ya usalama. Jozi moja tu inahitaji kulingana.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Ili kuthibitisha usimbaji fiche wa mwanzo hadi mwisho na {name}, linganisha nambari zilizo hapo juu na kifaa chao. Pia, wanaweza kupiga skani msimbo wako na kifaa chao.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Inabadilika kuwa nambari ya usalama", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Nambari za usalama zinasasishwa katika kipindi cha mpito ili kuwezesha vipengele vya faragha vijavyo katika Signal.\n\n", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Ili kuthibitisha nambari za usalama, linganisha kadi ya rangi na kifaa cha muwasiliani wako. Kama hivi havilingani, jaribu jozi nyingine ya nambari ya usalama. Jozi moja tu inahitaji kulingana.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Unahitaji usaidizi?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Nimeelewa", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Nambari ya usalama itaundwa na mtu huyu baada ya kubadilishana nao jumbe.", @@ -1267,10 +1359,6 @@ "messageformat": "Tazama media za hivi majuzi", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Ili kuthibitisha usalama kwenye msimbo wa end-to-end na {name}, linganisha nambari zilizopo juu na kifaa chao. Pia, wanaweza kupiga skani na msimbo wa qr uliopo hapo juu.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Bado haujabadilishana ujumbe na wasiliano huu. Nambari yako ya usalama na wao itapatikana baada ya ujumbe wa kwanza." }, @@ -1334,17 +1422,17 @@ "messageformat": "Maelezo", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Futa", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Futa jumbe", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Ungependa kufuta gumzo?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Futa ujumbe?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Gumzo hili litafutwa kwenye kifaa hiki.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Jumbe kwenye gumzo hili zitafutwa kutoka kwenye kifaa hiki. Bado unaweza kutafuta gumzo hili baada ya kufuta jumbe.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Ondoka kwenye kikundi", @@ -1438,6 +1526,14 @@ "messageformat": "Historia ya jumbe zako za gumzo zote mbili zimeunganishwa hapa.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} inamilikiwa na {conversationTitle}. Nyote ni wanachama wa {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} inamilikiwa na {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Kijipicha cha taswira kutoka kwa ujumbe ulionukuliwa", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Piga Tena", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Anza Kupiga Simu", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Jiunge na Mazungumzo ya Simu", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Maikrofoni imenyamazishwa kufuatia ukubwa wa simu", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Arifa za simu", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Mazungumzo ya simu yamejaa", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Jiunge", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Anza", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Wito wa simu umejaa", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera imezimwa", @@ -1621,10 +1725,6 @@ "messageformat": "Washa kamera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Nyamazisha", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Maikrofoni imezimwa", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Washa maikrofoni", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Shiriki", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Uwasilishaji umezimwa", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Acha kuwasilisha", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Piga", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Kikundi ni kikubwa sana kuweza kuwapigia washiriki.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Wezesha kupiga simu", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Zima sauti ya kuitana", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Washa sauti ya kuitana", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Chaguzi zaidi", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Wewe", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kamera yako imezimwa", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Tazama Nambari za Usalama", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Ujumbe", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Tazama Nambari za Usalama", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Imeshindikana kupata nambari ya simu. Angalia muunganisho wa mtandao wako kisha ujaribu tena.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Uhariri unaweza kufanywa ndani ya saa 3 kutoka muda uliotuma ujumbe huu.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Mabadiliko yanaweza kufanywa ndani ya saa 3 kutoka muda uliotuma ujumbe huu.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Ujumbe huu umefutwa.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Kiambatishi ni kikubwa sana hakiwezi kuonekana.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Baadhi ya viambatishi ni vikubwa mno haviwezi kuonekana.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Imeshindwa kuchukua taarifa za michango", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal beta pekee", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Kuhariri ujumbe kunapatikana kwa watumiaji wa beta wa Signal pekee. Ukihariri ujumbe, utaonekana kwa watu walio kwenye toleo jipya la beta la Signal pekee.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Hariri Ujumbe", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Ukihariri ujumbe, utaonekana kwa watu walio kwenye toleo jipya la Signal pekee. Wataweza kuona kuwa umehariri ujumbe.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Unapigiwa simu ya video...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Simu ya kawaida uliyopiga", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Simu ya video uliyopiga", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} anakupigia simu", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Inaunganisha tena...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {mtu {count,number}} other {watu {count,number}}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Simu ya sauti", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Tamatisha", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Ondoka", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Zima mic", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Washa mic", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Sauti ya kuitana imewashwa", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Sauti ya kuitana imezimwa", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Mipangilio", @@ -3468,13 +3668,25 @@ "messageformat": "Mazungumzo ya simu ya skrini nzima", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Badilisha utumie mtazamo wa gridi", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Badili mtazamo", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Badilisha utumie mwonekano wa mnenaji", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Mtazamo wa kigridi", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Mtazamo wa pembeni", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Mtazamo wa mzungumzaji", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Mtazamo umesasishwa", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Ondoka kwenye mazungumzo ya simu", @@ -3576,6 +3788,14 @@ "messageformat": "Sawa", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Haiwezekani kuhariri ujumbe", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Mabadiliko {max,number} tu yanaweza kufanywa kwenye ujumbe huu.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Samahani, kiungo hicho cha sgnl:// hakikuwa sahihi!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Jina la mtumiaji", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Kuna tatizo limetokea kwenye jina lako la mtumiaji, halijaandikishwa tena katika akaunti yako.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Futa jina la mtumiaji", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Unda Jina la Mtumiaji", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Msimbo au kiungo cha QR", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Jina la mtumiaji linahitaji kuwekwa upya", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Kiungo cha jina la mtumiaji kinahitaji kuwekwa upya", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Shiriki jina lako la mtumiaji", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Futa jina la mtumiaji", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Hii itaondoa jina lako la mtumiaji, na kuwezesha watumiaji wengine kulitumia. Una uhakika?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Hii itailondoa jina lako la mtumiaji na kuzima msimbo na kiungo chako cha QR. \"{username}\" atapatikana ili wengine waidai. Una uhakika?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Hutaweza tena kushiriki au kutazama stori. Masasisho ya stori uliyoshiriki hivi karibuni pia yatafutwa.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Lugha", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Lugha", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Lugha ya Mfumo", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Tafuta lugha", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Hakuna matokeo ya \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Weka", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Anzisha tena Signal ili kuweka mabadiliko", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Ili kubadili lugha, programu inapaswa kuanzishwa tena.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Anzisha tena", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Sasisha toleo {version} lililopo", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Kulikuwa na hitilafu wakati wa kuhifadhi mipangilio yako. Tafadhali jaribu tena.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Ujumbe", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Mitindo zaidi", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Weka upya", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Imekamilika", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Rangi ya kiungo cha jina la mtumiaji, {index,number} ya {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Ukiweka upya mipangilio ya msimbo wa QR, msimbo wa QR uliopo hautafanya kazi tena.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Kuweka upya kiungo...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Msimbo wa QR na kiungo hazijawekwa. Angalia muunganisho wako wa mtandao na ujaribu tena.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Sajili jina lako la Mtumiaji la Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "imehaririwa", + "messageformat": "Imehaririwa", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Tuma Tena", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Vitendo zaidi", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Simu", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Simu mpya", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Simu mpya", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Vitendo zaidi", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Futa historia ya simu", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Je, ungetaka kufuta historia ya simu?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Hii itafuta kabisa historia ya simu zote", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Futa", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Historia ya simu imefutwa", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Bofya ili kutazama au kuanzisha simu", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Tafuta", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Chuja kwa zilizokoswa", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Geuza", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Hakuna simu za hivi karibuni. Anza kwa kumpigia rafiki.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Hakuna matokeo ya \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Simu Inayoingia", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Simu Inayopigwa", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Simu Fifi", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Mazungumzo ya simu ya kikundi", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Hakuna mazungungumzo ya hivi karibuni.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Hakuna matokeo ya \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Simu ya kawaida uliyopiga} other {Simu ya kawaida inayopigwa}}} Video {{direction, select, Outgoing {Simu ya video uliyopiga} other {Simu ya video uliyopigiwa}}} Group {{direction, select, Outgoing {Kupiga simu ya kikundi} other {Simu ya kikundi inayopigwa}}} other {{direction, select, Outgoing {Simu inayotoka} other {Simu inaingia}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Simu ya kawaida fifi} Video {Umekosa simu ya video} Group {Simu fifi ya kikundi} other {Simu uliyokosa}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Simu ya kawaida isiyopokelewa} Video {Simu ya video ambayo haikujibiwa} Group {Simu ya kikundi isiyopokelewa} other {Simu ambayo haijapokelewa}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Simu ya kawaida iliyokataliwa} Video {Simu ya video iliyokataliwa} Group {Simu ya kikundi iliyokataliwa} other {Simu iliyokataliwa}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {Mwingine {count,number} anaandika.} other {Wengine {count,number} wanaandika.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Kuna Lipi Jipya?", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Mabadiliko madogo, marekebisho ya bugs na uboreshaji wa utendaji. Asante kwa kutumia Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Sasisho hili linajumuisha maboresho machache ya simu za kawaida na za video, na masasisho ya baadhi ya hati (asante, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Sasa unaweza kubadilisha lugha uliyochagua katika Signal bila kubadili mipangilio ya mfumo wako (Mipangilio ya Signal> Muonekano > Lugha)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Tumebadili aikoni za arifa zinazoonekana kwenye taarifa za kikundi, kama vile pale mtu anapojiunga katika kikundi kipya. Aikoni hizi zinasaidia kuboresha urahisi wa kusoma, hasa kama unapendelea Mandhari Meusi. Aikoni zilizotangulia hazikuweza kutumia mandhari meusi vyema. Aikoni mpya zimezaliwa na kuumbwa nayo." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Tumerekebisha ucheleweshaji mfupi ambao wakati mwingine ulitokea wakati wa kujiunga na chumba cha kupiga simu kwenye vifaa vya macOS, jambo ambalo linapaswa kuondoa angalau kisingizio kimoja cha kuchelewa mkutanoni kwa nusu sekunde." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Tumerekebisha mpito wa uhuishaji wa video za picha mtu anapojiunga au anapoondoka kwenye simu ya kikundi. Unapoona uso wa rafiki kwenye muonekano, hiyo ni harakati ya kijamii." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Sasa unaweza kubofya kwenye picha ya wasifu au avatar kwenye chanzo cha gumzo ili kufikia kwa haraka mipangilio ya gumzo au kutazama hadithi zozote ambazo hazikutazamwa kwenye gumzo hilo. Asante, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ta-IN/messages.json b/_locales/ta-IN/messages.json index ba9bf21076..e44497ad72 100644 --- a/_locales/ta-IN/messages.json +++ b/_locales/ta-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àź€àź°àź”àŻàź€àŻ àź€àźłàźźàŻ àźȘàźżàźŽàŻˆ", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àź’àź°àŻ àź€àź°àź”àŻàź€àŻàź€àźłàźȘàŻ àźȘàźżàźŽàŻˆ àźàź±àŻàźȘàźŸàŻàźŸàź€àŻ. àźšàŻ€àź™àŻàź•àźłàŻ àźȘàźżàźŽàŻˆàźŻàŻˆ àźšàź•àźČàŻ†àźŸàŻàź€àŻàź€àŻ, àźšàźżàź•àŻàź•àźČàŻˆàźšàŻ àźšàź°àźżàźšàŻ†àźŻàŻàźŻ àźšàźżàź•àŻàź©àźČàŻ àź†àź€àź°àź”àŻˆàź€àŻ àź€àŻŠàźŸàź°àŻàźȘàŻàź•àŻŠàźłàŻàźłàźČàźŸàźźàŻ. àźšàŻ€àź™àŻàź•àźłàŻ àź‰àźŸàź©àźŸàźżàźŻàźŸàź• àźšàźżàź•àŻàź©àźČàŻˆàźȘàŻ àźȘàźŻàź©àŻàźȘàźŸàŻàź€àŻàź€ àź”àŻ‡àźŁàŻàźŸàŻàźźàŻ†àź©àŻàź±àźŸàźČàŻ, àź‰àź™àŻàź•àźłàŻ àź€àź°àź”àŻˆ àźšàŻ€àź•àŻàź•àźżàź”àźżàźŸàŻàźŸàŻ àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź€àŻŠàźŸàź™àŻàź•àź”àŻàźźàŻ.\n\nàź‡àź™àŻàź•àŻ àźšàŻ†àźČàŻàź”àź€àź©àŻ àźźàŻ‚àźČàźźàŻ àź†àź€àź°àź”àŻˆàź€àŻ àź€àŻŠàźŸàź°àŻàźȘàŻàź•àŻŠàźłàŻàźłàź”àŻàźźàŻ: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àźŽàźČàŻàźČàźŸ àź€àź°àź”àŻˆàźŻàŻàźźàŻ àźšàŻ€àź•àŻàź•àźż àźźàź±àŻàź€àŻŠàźŸàź•àŻàź•àźźàŻ àźšàŻ†àźŻàŻ", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àź€àź°àź”àŻˆ àźšàŻ€àź•àŻàź•àźż àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź€àŻŠàźŸàź™àŻàź•àź”àŻàźźàŻ", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àźŽàźČàŻàźČàźŸ àź€àź°àź”àŻˆàźŻàŻàźźàŻ àźšàźżàź°àźšàŻàź€àź°àźźàźŸàź• àźšàŻ€àź•àŻàź• àź”àŻ‡àźŁàŻàźŸàŻàźźàźŸ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àź‰àź™àŻàź•àźłàŻ àźźàŻ†àźšàŻ‡àźœàŻ àź”àź°àźČàźŸàź±àŻ àźźàź±àŻàź±àŻàźźàŻ àźźàŻ€àźŸàźżàźŻàźŸ àź…àź©àŻˆàź€àŻàź€àŻàźźàŻ àź‡àźšàŻàź€ àźŸàźżàź”àŻˆàźžàźżàźČàŻ àź‡àź°àŻàźšàŻàź€àŻ àźšàźżàź°àźšàŻàź€àź°àźźàźŸàź• àźšàŻ€àź•àŻàź•àźȘàŻàźȘàźŸàŻàźźàŻ. àź‡àźšàŻàź€ àźŸàźżàź”àŻˆàźžàŻˆ àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź‡àźŁàŻˆàź€àŻàź€ àźȘàźżàź±àź•àŻ àźšàŻ€àź™àŻàź•àźłàŻ SignalàźàźȘàŻ àźȘàźŻàź©àŻàźȘàźŸàŻàź€àŻàź€ àźźàŻàźŸàźżàźŻàŻàźźàŻ. àź‡àź€àŻ àź‰àź™àŻàź•àźłàŻ àźƒàźȘàŻ‹àź©àźżàźČàŻ àź‡àź°àŻàźšàŻàź€àŻ àźŽàźšàŻàź€ àź€àź°àź”àŻˆàźŻàŻàźźàŻ àźšàŻ€àź•àŻàź•àźŸàź€àŻ.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àź‰àź™àŻàź•àźłàŻ àź€àź°àź”àŻàź€àŻàź€àźłàź€àŻàź€àźżàź©àŻ àźȘàź€àźżàźȘàŻàźȘàŻ Signal àź‡àź©àŻ àź‡àźšàŻàź€àźȘàŻ àźȘàź€àźżàźȘàŻàźȘàŻ‹àźŸàŻ àźȘàŻŠàź°àŻàźšàŻàź€àź”àźżàźČàŻàźČàŻˆ. àź‰àź™àŻàź•àźłàŻ àź•àźŁàźżàź©àźżàźŻàźżàźČàŻ Signal àź‡àź©àŻ àźȘàŻàź€àźżàźŻ àźȘàź€àźżàźȘàŻàźȘàŻˆàź€àŻ àź€àźżàź±àź•àŻàź•àźżàź±àŻ€àź°àŻàź•àźłàŻ àźŽàź©àŻàźȘàź€àŻˆ àź‰àź±àŻàź€àźżàźȘàŻàźȘàźŸàŻàź€àŻàź€àź”àŻàźźàŻ.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&àź•àŻ‡àźŸàźȘàŻàźȘàŻ", @@ -300,6 +316,70 @@ "messageformat": "àźšàźŸàźŸàŻàźžàŻ", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àź‰àź™àŻàź•àźłàŻ àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àźżàźČàŻ àźàź€àŻ‹ àź€àź”àź±àŻ àźšàźŸàźšàŻàź€àŻ àź”àźżàźŸàŻàźŸàź€àŻ, àź‡àź©àźż àź’àź°àŻàźȘàŻ‹àź€àŻàźźàŻ àź‰àź™àŻàź•àźłàŻ àź•àźŁàź•àŻàź•àźżàźČàŻ àźšàźżàźŻàźźàźżàź•àŻàź•àźȘàŻàźȘàźŸàź”àźżàźČàŻàźČàŻˆ. àźšàŻ€àź™àŻàź•àźłàŻ àźźàŻàźŻàź©àŻàź±àŻ àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź…àźźàŻˆàź•àŻàź•àźČàźŸàźźàŻ àź…àźČàŻàźČàź€àŻ àźȘàŻàź€àźżàźŻàź€àŻˆàź€àŻ àź€àŻ‡àź°àŻàźšàŻàź€àŻ†àźŸàŻàź•àŻàź•àźČàźŸàźźàŻ.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àź‡àźȘàŻàźȘàŻ†àźŸàźŽàŻàź€àŻ‡ àźšàź°àźżàźȘàźŸàź°àŻ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àź‰àź™àŻàź•àźłàŻ QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻ àźźàź±àŻàź±àŻàźźàŻ àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻ àź‡àźŁàŻˆàźȘàŻàźȘàźżàźČàŻ àźàź€àŻ‹ àź€àź”àź±àŻ àźšàźŸàźšàŻàź€àŻàź”àźżàźŸàŻàźŸàź€àŻ, àź…àź€àŻ àź‡àź©àźż àźšàŻ†àźČàŻàźČàŻàźȘàźŸàźżàźŻàźŸàź•àźŸàź€àŻ. àźźàź±àŻàź±àź”àź°àŻàź•àźłàŻàźŸàź©àŻ àźȘàź•àźżàź° àźȘàŻàź€àźżàźŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻˆ àź‰àź°àŻàź”àźŸàź•àŻàź•àź”àŻàźźàŻ.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àź‡àźȘàŻàźȘàŻ†àźŸàźŽàŻàź€àŻ‡ àźšàź°àźżàźȘàźŸàź°àŻ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àź€àźŸàź”àźČàŻàź•àźłàŻˆàź•àŻ àź•àźŸàźŸàŻàźŸàŻ", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àź€àźŸàź”àźČàŻàź•àźłàŻˆ àźźàź±àŻˆ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àź’àź°àŻ àźȘàźżàźŽàŻˆ àźàź±àŻàźȘàźŸàŻàźŸàź€àŻ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} àźȘàźŸàźżàź•àŻàź•àźŸàź€àź”àŻˆ", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àźȘàźŸàźżàź•àŻàź•àźŸàź€àź€àźŸàź•àź•àŻ àź•àŻàź±àźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àźšàźŸàźŸàŻàźžàŻ", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻàź•àźłàŻ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àźžàŻàźŸàŻ‹àź°àŻ€àźžàŻ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àź…àźźàŻˆàźȘàŻàźȘàŻàź•àźłàŻ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal àźČàŻˆàźȘàŻ àźȘàŻàź€àŻàźȘàŻàźȘàźżàź•àŻàź•àź”àŻàźźàŻ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àź”àźżàź”àź°àźźàŻ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àźźàŻ€àźŁàŻàźŸàŻàźźàŻ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àź‡àźšàŻàź€ àźšàźŸàźŸàŻàźžàŻ àź•àźŸàźȘàŻàźȘàź•àźȘàŻàźȘàźŸàŻàź€àŻàź€àźȘàŻàźȘàźŸàŻàźŸàŻ, àźȘàŻàź€àźżàźŻ àźšàŻ†àźŻàŻàź€àźżàź•àźłàŻ àź”àźšàŻàź€àźŸàźČàŻ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź‡àź©àŻàźȘàźŸàź•àŻàźžàźżàźČàŻ àź€àŻ‹àź©àŻàź±àŻàźźàŻ.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àź‡àź°àŻàźšàŻàź€àźŸàźČàŻàźźàŻ àź…àźŽàŻˆàź•àŻàź•àź”àŻàźźàŻ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àźȘàź°àź”àźŸàźŻàźżàźČàŻàźČàŻˆ, àźàź±àŻàź•àźżàź±àŻ‡àź©àŻ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻˆàź€àŻ àź€àŻŠàźŸàź°àź”àŻàźźàŻ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàź•àźłàŻ àźȘàŻàź€àŻàźȘàŻàźȘàźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàź•àźżàź©àŻàź±àź©.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àźźàŻ‡àźČàŻàźźàŻ àź…àź±àźżàź•", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àźźàŻàźšàŻàź€àŻˆàźŻ àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àź…àźŸàŻàź€àŻàź€ àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻ àźȘàź€àźżàźȘàŻàźȘàŻ, {index,number} / {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àźšàź°àźżàźȘàźŸàź°àŻàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àźŸàź•àź•àŻ àź•àŻàź±àźż", @@ -663,33 +747,41 @@ "messageformat": "àźšàź°àźżàźȘàźŸàź°àŻàźȘàŻàźȘàŻˆ àźšàŻ€àź•àŻàź•àŻ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} àź‡àź©àŻ àźŽàźŁàŻàźŸàŻ-àźŸàŻ-àźŽàźŁàŻàźŸàŻ àźŽàź©àŻàź•àŻàź°àźżàźȘàŻàź·àź©àŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź•àŻàź•, àźźàŻ‡àźČàŻ‡ àź‰àźłàŻàźł àźŽàźŁàŻàź•àźłàŻˆ àź…àź”àź±àŻàź±àźżàź©àŻ àźŸàźżàź”àŻˆàźžàŻ àź‰àźŸàź©àŻ àź’àźȘàŻàźȘàźżàźŸàź”àŻàźźàŻ. àź…àź”àź°àŻàź•àźłàŻ àź€àź™àŻàź•àźłàŻ àźŸàźżàź”àŻˆàźšàźżàźČàŻ àź‡àź°àŻàź•àŻàź•àŻàźźàŻ àź‰àź™àŻàź•àźłàŻ àź•àŻàź±àźżàźŻàŻ€àźŸàŻàźŸàŻˆ àźžàŻàź•àŻ‡àź©àŻ àźšàŻ†àźŻàŻàźŻàźČàźŸàźźàŻ.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àźźàŻ‡àźČàŻàźźàŻ àź…àź±àźżàź•", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} àź‡àź©àŻ àźŽàźŁàŻàźŸàŻ-àźŸàŻ-àźŽàźŁàŻàźŸàŻ àźŽàź©àŻàź•àŻàź°àźżàźȘàŻàź·àź©àŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź•àŻàź•, àźźàŻ‡àźČàŻ‡ àź‰àźłàŻàźł àź”àźŁàŻàźŁ àź…àźŸàŻàźŸàŻˆàźŻàŻˆ àź…àź”àź±àŻàź±àźżàź©àŻ àźŸàźżàź”àŻˆàźžàŻ àź‰àźŸàź©àŻ àźȘàŻŠàź°àŻàź€àŻàź€àźż àźŽàźŁàŻàź•àźłàŻˆ àź’àźȘàŻàźȘàźżàźŸàź”àŻàźźàŻ. àź‡àź”àŻˆ àźȘàŻŠàź°àŻàźšàŻàź€àź”àźżàźČàŻàźČàŻˆ àźŽàź©àŻàź±àźŸàźČàŻ, àźźàź±àŻàź± àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàź•àźłàŻ àźœàŻ‹àźŸàźżàźŻàŻˆ àźźàŻàźŻàź±àŻàźšàźżàź•àŻàź•àź”àŻàźźàŻ. àź’àź°àŻ àźœàŻ‹àźŸàźż àźźàźŸàŻàźŸàŻàźźàŻ‡ àźȘàŻŠàź°àŻàźšàŻàź€ àź”àŻ‡àźŁàŻàźŸàŻàźźàŻ.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} àź‡àź©àŻ àźŽàźŁàŻàźŸàŻ-àźŸàŻ-àźŽàźŁàŻàźŸàŻ àźŽàź©àŻàź•àŻàź°àźżàźȘàŻàź·àź©àŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź•àŻàź•, àźźàŻ‡àźČàŻ‡ àź‰àźłàŻàźł àźŽàźŁàŻàź•àźłàŻˆ àź…àź”àź±àŻàź±àźżàź©àŻ àźŸàźżàź”àŻˆàźžàŻ àź‰àźŸàź©àŻ àź’àźȘàŻàźȘàźżàźŸàź”àŻàźźàŻ. àź…àź”àź°àŻàź•àźłàŻ àź€àź™àŻàź•àźłàŻ àźŸàźżàź”àŻˆàźšàźżàźČàŻ àź‡àź°àŻàź•àŻàź•àŻàźźàŻ àź‰àź™àŻàź•àźłàŻ àź•àŻàź±àźżàźŻàŻ€àźŸàŻàźŸàŻˆ àźžàŻàź•àŻ‡àź©àŻ àźšàŻ†àźŻàŻàźŻàźČàźŸàźźàŻ.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàź•àźłàźżàźČàŻ àźźàźŸàź±àŻàź±àź™àŻàź•àźłàŻ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal àź‡àźČàŻ àź”àź°àź”àźżàź°àŻàź•àŻàź•àŻàźźàŻ àź€àź©àźżàźŻàŻàź°àźżàźźàŻˆ àź…àźźàŻàźšàź™àŻàź•àźłàŻˆ àź‡àźŻàź•àŻàź•, àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàź•àźłàŻ àź•àŻàź±àźżàźȘàŻàźȘàźżàźŸàŻàźŸ àźšàźżàźČàŻˆ àźźàźŸàź±àŻàź±àźȘàŻàźȘàźŸàŻàźźàŻ àź•àźŸàźČàź€àŻàź€àźżàźČàŻ àźȘàŻàź€àŻàźȘàŻàźȘàźżàź•àŻàź•àźȘàŻàźȘàźŸàź”àŻàźłàŻàźłàź©.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàź•àźłàŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź•àŻàź•, àź‰àź™àŻàź•àźłàŻ àź€àŻŠàźŸàź°àŻàźȘàźżàź©àŻ àźŸàźżàź”àŻˆàźžàŻ àź‰àźŸàź©àŻ àź”àźŁàŻàźŁ àź…àźŸàŻàźŸàŻˆàźŻàŻˆàźȘàŻ àźȘàŻŠàź°àŻàź€àŻàź€àź”àŻàźźàŻ. àź‡àź”àŻˆ àźȘàŻŠàź°àŻàźšàŻàź€àź”àźżàźČàŻàźČàŻˆ àźŽàź©àŻàź±àźŸàźČàŻ, àźźàź±àŻàź± àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàź•àźłàŻ àźœàŻ‹àźŸàźżàźŻàŻˆ àźźàŻàźŻàź±àŻàźšàźżàź•àŻàź•àź”àŻàźźàŻ. àź’àź°àŻ àźœàŻ‹àźŸàźż àźźàźŸàŻàźŸàŻàźźàŻ‡ àźȘàŻŠàź°àŻàźšàŻàź€ àź”àŻ‡àźŁàŻàźŸàŻàźźàŻ.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àź‰àź™àŻàź•àźłàŻàź•àŻàź•àŻ àź‰àź€àź”àźż àź”àŻ‡àźŁàŻàźŸàŻàźźàźŸ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àź…àź±àźżàźšàŻàź€àŻàź•àŻŠàźŁàŻàźŸàŻ‡àź©àŻ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àź‡àź”àź°àŻàźŸàź©àŻ àźšàŻ€àź™àŻàź•àźłàŻ àźšàŻ†àźŻàŻàź€àźżàź•àźłàŻˆàźȘàŻ àźȘàź°àźżàźźàźŸàź±àźżàźŻ àźȘàźżàź±àź•àŻ àź…àź”àź°àŻàźŸàź©àŻ àź’àź°àŻ àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻ àź‰àź°àŻàź”àźŸàź•àŻàź•àźȘàŻàźȘàźŸàŻàźźàŻ.", @@ -1267,10 +1359,6 @@ "messageformat": "àźšàźźàŻ€àźȘàź€àŻàź€àźżàźŻ àźŠàźŸàź•àź™àŻàź•àźłàŻˆàź•àŻ àź•àźŸàźŁàŻàź•", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} àź‰àźŸàź©àŻ àź‰àź™àŻàź•àźłàŻ àźŽàźŁàŻàźŸàŻ-àźŸàŻ-àźŽàźŁàŻàźŸàŻ àźŽàź©àŻàź•àŻàź°àźżàźȘàŻàź·àź©àźżàź©àŻ àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź•àŻàź•, àźźàŻ‡àźČàŻ‡ àź‰àźłàŻàźł àźŽàźŁàŻàź•àźłàŻˆ àź…àź”àź±àŻàź±àźżàź©àŻ àźŸàźżàź”àŻˆàźžàŻ àź‰àźŸàź©àŻ àź’àźȘàŻàźȘàźżàźŸàź”àŻàźźàŻ. àźźàŻ‡àźČàŻ‡ àź‰àźłàŻàźł QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻàźŸàŻˆàźŻàŻàźźàŻ àź…àź”àź°àŻàź•àźłàŻ àźžàŻàź•àŻ‡àź©àŻ àźšàŻ†àźŻàŻàźŻàźČàźŸàźźàŻ.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àź‡àźšàŻàź€ àź€àŻŠàźŸàź°àŻàźȘàŻàźŸàź©àŻ àźšàŻ€àź™àŻàź•àźłàŻ àź‡àź€àŻàź”àź°àŻˆ àźŽàźšàŻàź€ àźšàŻ†àźŻàŻàź€àźżàź•àźłàŻˆàźŻàŻàźźàŻ àźȘàź°àźżàźźàźŸàź±àź”àźżàźČàŻàźČàŻˆ. àź…àź”àź°àŻàź•àźłàŻàźŸàź©àźŸàź© àź‰àź™àŻàź•àźłàŻ àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻ àźźàŻàź€àźČàŻ àźšàŻ†àźŻàŻàź€àźżàź•àŻàź•àŻàźȘàŻ àźȘàźżàź±àź•àŻ àź•àźżàźŸàŻˆàź•àŻàź•àŻàźźàŻ." }, @@ -1334,17 +1422,17 @@ "messageformat": "àź€àź•àź”àźČàŻ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àźšàŻ€àź•àŻàź•àŻ", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻàź•àźłàŻˆ àźšàŻ€àź•àŻàź•àŻ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àźšàźŸàźŸàŻàźŸàŻˆ àźšàŻ€àź•àŻàź• àź”àŻ‡àźŁàŻàźŸàŻàźźàźŸ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻàź•àźłàŻˆ àźšàŻ€àź•àŻàź• àź”àŻ‡àźŁàŻàźŸàŻàźźàźŸ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àź‡àź€àŻ àź…àź°àźŸàŻàźŸàŻˆ àź‡àźšàŻàź€ àźŸàźżàź”àŻˆàźšàźżàźČàźżàź°àŻàźšàŻàź€àŻ àźšàŻ€àź•àŻàź•àźȘàŻàźȘàźŸàŻàźźàŻ.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àź‡àźšàŻàź€ àźšàźŸàźŸàŻàźŸàźżàźČàŻ àź‰àźłàŻàźł àźźàŻ†àźšàŻ‡àźœàŻàź•àźłàŻ àź‡àźšàŻàź€ àźŸàźżàź”àŻˆàźžàźżàźČàźżàź°àŻàźšàŻàź€àŻ àźšàŻ€àź•àŻàź•àźȘàŻàźȘàźŸàŻàźźàŻ. àźźàŻ†àźšàŻ‡àźœàŻàź•àźłàŻˆ àźšàŻ€àź•àŻàź•àźżàźŻ àźȘàźżàź±àź•àŻàźźàŻ àźšàŻ€àź™àŻàź•àźłàŻ àź‡àźšàŻàź€ àźšàźŸàźŸàŻàźŸàŻˆàź€àŻ àź€àŻ‡àźŸàźČàźŸàźźàŻ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àź•àŻàźŽàŻàź”àźżàźČàŻàź°àŻàźšàŻàź€àŻ àź”àźżàźČàź•àŻ", @@ -1438,6 +1526,14 @@ "messageformat": "àź‡àź°àźŁàŻàźŸàŻ àźšàźŸàźŸàŻàź•àźłàŻàź•àŻàź•àźŸàź© àź‰àź™àŻàź•àźłàŻ àźźàŻ†àźšàŻ‡àźœàŻ àź”àź°àźČàźŸàź±àŻ àź‡àź™àŻàź•àŻ‡ àź‡àźŁàŻˆàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàŻàźłàŻàźłàź€àŻ.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} àź•àŻàź•àŻ àźšàŻŠàźšàŻàź€àźźàźŸàź©àź€àŻ. àźšàŻ€àź™àŻàź•àźłàŻ àź‡àź°àŻàź”àź°àŻàźźàŻ {sharedGroup} àź‡àź©àŻ àź‰àź±àŻàźȘàŻàźȘàźżàź©àź°àŻàź•àźłàŻ.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} àź•àŻàź•àŻ àźšàŻŠàźšàŻàź€àźźàźŸàź©àź€àŻ", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àźźàŻ‡àź±àŻàź•àŻ‹àźłàŻ àźšàŻ†àźŻàŻàź€àźżàźŻàźżàźČàźżàź°àŻàźšàŻàź€àŻ àźȘàźŸàź€àŻàź€àźżàź©àŻ àźšàźżàź±àŻ àź‰àź°àŻàź”àźźàŻ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź…àźŽàŻˆ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻˆàź€àŻ àź€àŻŠàźŸàź™àŻàź•àŻ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàźżàźČàŻ àźšàŻ‡àź°àŻ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàźżàź©àŻ àź…àźłàź”àŻ àź•àźŸàź°àźŁàźźàźŸàź• àźźàŻˆàź•àŻàź°àŻ‹àźƒàźȘàŻ‹àź©àŻ àź’àźČàźżàźŻàźŸàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻ àź…àź±àźżàź”àźżàźȘàŻàźȘàŻàź•àźłàŻ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻ àźšàźżàź°àźźàŻàźȘàźżàźŻàŻàźłàŻàźłàź€àŻ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àźȘàŻàź•àŻˆàźȘàŻàźȘàźŸ àź•àź°àŻàź”àźż", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àź‡àźŁàŻˆàź•", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àź€àŻŠàźŸàź™àŻàź•àŻ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àź•àźŸàźČàŻ àźƒàźȘàŻàźČàŻ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àźȘàŻàź•àŻˆàźȘàŻàźȘàźŸ àź•àź°àŻàź”àźż àźźàŻàźŸàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", @@ -1621,10 +1725,6 @@ "messageformat": "àźȘàŻàź•àŻˆàźȘàŻàźȘàźŸ àź•àź°àŻàź”àźżàźŻàŻˆ àź€àźŻàźŸàź°àŻ àźšàŻ†àźŻàŻàź•", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àź’àźČàźżàźŻàźŸàź•àŻàź•àŻ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àźźàŻˆàź•àŻàź°àŻ‹àźƒàźȘàŻ‹àź©àŻ àźźàŻàźŸàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àźźàŻˆàź•àŻ àź’àźČàźż àź‡àźŻàź•àŻàź•àŻ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àźȘàź•àźżàź°àŻ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àź”àźŽàź™àŻàź•àŻàź€àźČàŻ àźźàŻàźŸàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àź”àźŽàź™àŻàź•àŻàź”àź€àŻˆ àźšàźżàź±àŻàź€àŻàź€àŻàź™àŻàź•àźłàŻ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àź…àźŽàŻˆ", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àźŽàźŁàŻàźŁàźżàź•àŻàź•àŻˆ àź•àŻ‚àźŸàźżàźŻàź€àźŸàźČàŻ àź•àŻàźŽàŻàź”àźżàźČàŻ àź‰àźłàŻàźł àź…àź©àŻˆàź”àź°àŻˆàźŻàŻàźźàŻ àź…àźŽàŻˆàź•àŻàź• àź‡àźŻàźČàźŸàź€àŻ", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻˆ àź‡àźŻàź•àŻàź•àŻ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àź°àźżàź™àŻàź•àźżàź™àŻàź•àŻˆ àź†àźƒàźȘàŻ àźšàŻ†àźŻàŻàźŻàŻàźźàŻ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àź°àźżàź™àŻàź•àźżàź™àŻàź•àŻˆ àź†àź©àŻ àźšàŻ†àźŻàŻàźŻàŻàźźàŻ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àź…àź€àźżàź• àź”àźżàź°àŻàźȘàŻàźȘàź€àŻàź€àŻ‡àź°àŻàź”àŻàź•àźłàŻ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àźšàŻ€àź™àŻàź•àźłàŻ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àź‰àź™àŻàź•àźłàŻ àźȘàŻàź•àŻˆàźȘàŻàźȘàźŸ àź•àź°àŻàź”àźż àź…àźŁàŻˆàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàŻàźłàŻàźłàź€àŻ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàźŁàŻˆàź•àŻ àź•àźŸàźŸàŻàźŸàŻ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àźȘàźŸàź€àŻàź•àźŸàźȘàŻàźȘàŻ àźŽàźŁàŻàźŁàŻˆàź•àŻ àź•àźŸàźŸàŻàźŸàŻ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "àź€àŻŠàźČàŻˆàźȘàŻ‡àźšàźż àźŽàźŁàŻàźŁàŻˆàźȘàŻ àźȘàŻ†àź±àŻàź”àź€àźżàźČàŻ àź€àŻ‹àźČàŻàź”àźż. àź‰àź™àŻàź•àźłàŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź€àŻàź€àŻ àźźàŻ€àźŁàŻàźŸàŻàźźàŻàźźàŻàźŻàź±àŻàźšàźżàź•àŻàź•àź”àŻàźźàŻ.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àźšàŻ€àź™àŻàź•àźłàŻ àź‡àźšàŻàź€ àźźàŻ†àźšàŻ‡àźœàŻˆ àź…àź©àŻàźȘàŻàźȘàźżàźŻàź€àźżàźČàźżàź°àŻàźšàŻàź€àŻ 3 àźźàźŁàźżàźšàŻ‡àź°àź€àŻàź€àźżàź±àŻàź•àŻàźłàŻ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź€àźżàź°àŻàź€àŻàź€àź™àŻàź•àźłàŻˆàźȘàŻ àźȘàźŻàź©àŻàźȘàźŸàŻàź€àŻàź€ àźźàŻàźŸàźżàźŻàŻàźźàŻ.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àźšàŻ€àź™àŻàź•àźłàŻ àź‡àźšàŻàź€ àźźàŻ†àźšàŻ‡àźœàŻˆ àź…àź©àŻàźȘàŻàźȘàźżàźŻàź€àźżàźČàźżàź°àŻàźšàŻàź€àŻ 24 àźźàźŁàźżàźšàŻ‡àź°àź€àŻàź€àźżàź±àŻàź•àŻàźłàŻ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź€àźżàź°àŻàź€àŻàź€àź™àŻàź•àźłàŻˆàźšàŻ àźšàŻ†àźŻàŻàźŻ àźźàŻàźŸàźżàźŻàŻàźźàŻ.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àź‡àźšàŻàź€ àźźàŻ†àźšàŻ‡àźœàŻ àźšàŻ€àź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àź•àźŸàźŸàŻàźŸ àźźàŻàźŸàźżàźŻàźŸàź€ àź…àźłàź”àŻàź•àŻàź•àŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻ àźȘàŻ†àź°àźżàź€àźŸàź• àź‰àźłàŻàźłàź€àŻ.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àźšàźżàźČ àź‡àźŁàŻˆàźȘàŻàźȘàŻàź•àźłàŻ àź•àźŸàźŸàŻàźŸ àźźàŻàźŸàźżàźŻàźŸàź€ àź…àźłàź”àŻàź•àŻàź•àŻ àźȘàŻ†àź°àźżàź€àźŸàź• àź‰àźłàŻàźłàź©.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àźšàź©àŻàź•àŻŠàźŸàŻˆ àź”àźżàź”àź°àź™àŻàź•àźłàŻˆàźȘàŻ àźȘàŻ†àź± àźźàŻàźŸàźżàźŻàź”àźżàźČàŻàźČàŻˆ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal àźȘàŻ€àźŸàŻàźŸàźŸ àźźàźŸàŻàźŸàŻàźźàŻ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻàź•àźłàŻˆàź€àŻ àź€àźżàź°àŻàź€àŻàź€àŻàź”àź€àŻ Signal àźȘàŻ€àźŸàŻàźŸàźŸ àźȘàźŻàź©àź°àŻàź•àźłàŻàź•àŻàź•àŻ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź•àźżàźŸàŻˆàź•àŻàź•àŻàźźàŻ. àźšàŻ€àź™àŻàź•àźłàŻ àź’àź°àŻ àźźàŻ†àźšàŻ‡àźœàŻˆàź€àŻ àź€àźżàź°àŻàź€àŻàź€àźżàź©àźŸàźČàŻ, àź…àź€àŻ Signal àźȘàŻ€àźŸàŻàźŸàźŸàź”àźżàź©àŻ àźšàźźàŻ€àźȘàź€àŻàź€àźżàźŻ àźȘàź€àźżàźȘàŻàźȘàźżàźČàŻ àź‰àźłàŻàźłàź”àź°àŻàź•àźłàŻàź•àŻàź•àŻ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź€àŻ†àź°àźżàźŻàŻàźźàŻ.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻˆàź€àŻ àź€àźżàź°àŻàź€àŻàź€àź”àŻàźźàŻ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àźšàŻ€àź™àŻàź•àźłàŻ àź’àź°àŻ àźźàŻ†àźšàŻ‡àźœàŻˆàź€àŻ àź€àźżàź°àŻàź€àŻàź€àźżàź©àźŸàźČàŻ, àź…àź€àŻ Signal àźȘàŻ€àźŸàŻàźŸàźŸàź”àźżàź©àŻ àźšàźźàŻ€àźȘàź€àŻàź€àźżàźŻ àźȘàź€àźżàźȘàŻàźȘàźżàźČàŻ àź‰àźłàŻàźłàź”àź°àŻàź•àźłàŻàź•àŻàź•àŻ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź€àŻ†àź°àźżàźŻàŻàźźàŻ. àźšàŻ€àź™àŻàź•àźłàŻ àź’àź°àŻ àźšàŻ†àźŻàŻàź€àźżàźŻàŻˆàź€àŻ àź€àźżàź°àŻàź€àŻàź€àźżàźŻàźżàź°àŻàźȘàŻàźȘàź€àŻˆ àź…àź”àź°àŻàź•àźłàźŸàźČàŻ àźȘàźŸàź°àŻàź•àŻàź• àźźàŻàźŸàźżàźŻàŻàźźàŻ.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àź‡àź©àŻàź•àźźàźżàź™àŻ àź”àŻ€àźŸàźżàźŻàŻ‹ àź…àźŽàŻˆàźȘàŻàźȘàŻâ€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àź”àŻ†àźłàźżàźšàŻàźšàŻ†àźČàŻàźČàŻàźźàŻ àź•àŻàź°àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àź”àŻ†àźłàźżàźšàŻàźšàŻ†àźČàŻàźČàŻàźźàŻ àź•àźŸàźŁàŻ†àźŸàźłàźż àź…àźŽàŻˆàźȘàŻàźȘàŻ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àź‰àź™àŻàź•àźłàŻˆ àź…àźŽàŻˆàź•àŻàź•àźżàź±àźŸàź°àŻ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź‡àźŁàŻˆàź•àŻàź•àźżàź±àź€àŻâ€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal àźšàźżàź•àŻàź©àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ àź•àźŸàźČàźźàŻ {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} àźšàźȘàź°àŻ} other {{count,number} àźšàźȘàź°àŻàź•àźłàŻ}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àź†àźŸàźżàźŻàŻ‹ àź…àźŽàŻˆàźȘàŻàźȘàŻ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àźźàŻàźŸàźżàź”àŻ", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àź”àźżàźČàź•àŻ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àźźàŻˆàź•àŻ àź†àźƒàźȘàŻ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àźźàŻˆàź•àŻ àź†àź©àŻ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àź°àźżàź™àŻàź•àźżàź™àŻ àź†àź©àŻ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àź°àźżàź™àŻàź•àźżàź™àŻàź•àŻˆ àź†àźƒàźȘàŻ àźšàŻ†àźŻàŻàźŻàŻàźźàŻ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àź…àźźàŻˆàźȘàŻàźȘàŻàź•àźłàŻ", @@ -3468,13 +3668,25 @@ "messageformat": "àźźàŻàźŽàŻàź€àŻàź€àźżàź°àŻˆ àź…àźŽàŻˆàźȘàŻàźȘàŻ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àź•àźŸàŻàźŸàź€àŻàź€àźżàź±àŻàź•àŻ àźźàźŸàź±àź”àŻàźźàŻ àźȘàźŸàź°àŻàź”àŻˆ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àź”àŻàźŻàŻ‚-àź àźźàźŸàź±àŻàź±àź”àŻàźźàŻ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àźžàŻàźȘàŻ€àź•àŻàź•àź°àŻàź•àŻàź•àŻ àźźàźŸàź±àź”àŻàźźàŻàźȘàźŸàź°àŻàź”àŻˆ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àź•àŻàź°àźżàźŸàŻ àź”àŻàźŻàŻ‚", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àźšàŻˆàźŸàŻàźȘàźŸàź°àŻ àź”àŻàźŻàŻ‚", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àźžàŻàźȘàŻ€àź•àŻàź•àź°àŻ àź”àŻàźŻàŻ‚", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àź”àŻàźŻàŻ‚ àźȘàŻàź€àŻàźȘàŻàźȘàźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻˆ àź”àźżàźŸàŻàź™àŻàź•àźłàŻ", @@ -3576,6 +3788,14 @@ "messageformat": "àźšàź°àźż", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻˆ àź€àźżàź°àŻàź€àŻàź€àźźàŻ àźšàŻ†àźŻàŻàźŻ àźźàŻàźŸàźżàźŻàźŸàź€àŻ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àź‡àźšàŻàź€ àźźàŻ†àźšàŻ‡àźœàźżàźČàŻ {max,number} àźźàŻàź±àŻˆ àźźàźŸàŻàźŸàŻàźźàŻ‡ àź€àźżàź°àŻàź€àŻàź€àźźàŻ àźšàŻ†àźŻàŻàźŻ àźźàŻàźŸàźżàźŻàŻàźźàŻ.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àźźàź©àŻàź©àźżàź•àŻàź•àź”àŻàźźàŻ, àź…àźšàŻàź€ sgnl:// àź‡àźŁàŻˆàźȘàŻàźȘàŻ àźȘàŻàź°àźżàźŻàź”àźżàźČàŻàźČàŻˆ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻ", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àź‰àź™àŻàź•àźłàŻ àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àźżàźČàŻ àźàź€àŻ‹ àź€àź”àź±àŻ àźšàźŸàźšàŻàź€àŻ àź”àźżàźŸàŻàźŸàź€àŻ, àź‡àź©àźż àź’àź°àŻàźȘàŻ‹àź€àŻàźźàŻ àź‰àź™àŻàź•àźłàŻ àź•àźŁàź•àŻàź•àźżàźČàŻ àźšàźżàźŻàźźàźżàź•àŻàź•àźȘàŻàźȘàźŸàź”àźżàźČàŻàźČàŻˆ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àźȘàźŻàź©àź°àŻ àźȘàŻ†àźŻàź°àŻˆ àźšàŻ€àź•àŻàź•àź”àŻàźźàŻ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻˆ àź‰àź°àŻàź”àźŸàź•àŻàź•àź”àŻàźźàŻ", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻ àź…àźČàŻàźČàź€àŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻ", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻˆ àźźàŻ€àźŸàŻàźŸàźźàŻˆàź•àŻàź• àź”àŻ‡àźŁàŻàźŸàŻàźźàŻ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻˆ àźźàŻ€àźŸàŻàźŸàźźàŻˆàź•àŻàź• àź”àŻ‡àźŁàŻàźŸàŻàźźàŻ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àź‰àź™àŻàź•àźłàŻ àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻˆàźȘàŻ àźȘàź•àźżàź°àź”àŻàźźàŻ", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àźȘàźŻàź©àź°àŻ àźȘàŻ†àźŻàź°àŻˆ àźšàŻ€àź•àŻàź•àź”àŻàźźàŻ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àź‡àź€àŻ àź‰àź™àŻàź•àźłàŻ àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻˆ àź…àź•àź±àŻàź±àźż, àźȘàźżàź± àźȘàźŻàź©àź°àŻàź•àźłàŻ àź…àź€àŻˆ àź‰àź°àźżàźźàŻˆàź•àŻ‹àź° àź…àź©àŻàźźàź€àźżàź•àŻàź•àŻàźźàŻ. àźšàŻ€àź™àŻàź•àźłàŻ àź‰àź±àŻàź€àźżàźŻàźŸàź• àź‰àźłàŻàźłàŻ€àź°àŻàź•àźłàźŸ?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àź‡àź€àŻ àź‰àź™àŻàź•àźłàŻ àźȘàźŻàź©àź°àŻ àźȘàŻ†àźŻàź°àŻˆ àź…àź•àź±àŻàź±àźż, àź‰àź™àŻàź•àźłàŻ QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻ àźźàź±àŻàź±àŻàźźàŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻˆ àźźàŻàźŸàź•àŻàź•àŻàźźàŻ. \"{username} \" àźźàź±àŻàź±àź”àź°àŻàź•àźłàŻ àź‰àź°àźżàźźàŻˆ àź•àŻ‹àź°àŻàź”àź€àź±àŻàź•àŻàź•àŻ àź•àźżàźŸàŻˆàź•àŻàź•àźȘàŻàźȘàŻ†àź±àŻàźźàŻ. àź‰àź±àŻàź€àźżàźŻàźŸàź• àź‰àźłàŻàźłàŻ€àź°àŻàź•àźłàźŸ?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àź‡àź©àźż àź‰àź™àŻàź•àźłàźŸàźČàŻ àźžàŻàźŸàŻ‹àź°àŻ€àź•àŻàź•àźłàŻˆàźȘàŻ àźȘàź•àźżàź°àź”àŻ‹ àźȘàźŸàź°àŻàź•àŻàź•àź”àŻ‹ àźźàŻàźŸàźżàźŻàźŸàź€àŻ. àźšàźźàŻ€àźȘàź€àŻàź€àźżàźČàŻ àźšàŻ€àź™àŻàź•àźłàŻ àźȘàź•àźżàź°àŻàźšàŻàź€ àźžàŻàźŸàŻ‹àź°àźż àźȘàŻàź€àŻàźȘàŻàźȘàźżàźȘàŻàźȘàŻàź•àźłàŻàźźàŻ àźšàŻ€àź•àŻàź•àźȘàŻàźȘàźŸàŻàźźàŻ.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àźźàŻ†àźŸàźŽàźż", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àźźàŻ†àźŸàźŽàźż", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àźšàźżàźžàŻàźŸàźźàŻ àźźàŻŠàźŽàźż", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àźźàŻŠàźŽàźżàź•àźłàŻˆàź€àŻ àź€àŻ‡àźŸàŻ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "''{searchTerm}\"-àź•àŻàź•àźŸàź© àźźàŻàźŸàźżàź”àŻàź•àźłàŻ àźŽàź€àŻàź”àŻàźźàŻ àź•àźżàźŸàŻˆàź•àŻàź•àź”àźżàźČàŻàźČàŻˆ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àź…àźźàŻˆàź•àŻàź•àź”àŻàźźàŻ", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àźȘàźŻàź©àŻàźȘàźŸàŻàź€àŻàź€ Signalàź àź°àŻ€àźžàŻàźŸàźŸàź°àŻàźŸàŻ àźšàŻ†àźŻàŻàźŻàź”àŻàźźàŻ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àźźàŻŠàźŽàźżàźŻàŻˆ àźźàźŸàź±àŻàź±, àźšàŻ†àźŻàźČàźżàźŻàŻˆ àź°àŻ€àźžàŻàźŸàźŸàź°àŻàźŸàŻ àźšàŻ†àźŻàŻàźŻ àź”àŻ‡àźŁàŻàźŸàŻàźźàŻ.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àź°àŻ€àźžàŻàźŸàźŸàź°àŻàźŸàŻ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "àźȘàź€àźżàźȘàŻàźȘàŻàź•àŻàź•àŻàźȘàŻ àźȘàŻàź€àŻàźȘàŻàźȘàźżàź•àŻàź•àź”àŻàźźàŻ {version} àź•àźżàźŸàŻˆàź•àŻàź•àźżàź±àź€àŻ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àź‰àź™àŻàź•àźłàŻ àź…àźźàŻˆàźȘàŻàźȘàŻàź•àźłàŻˆàźšàŻ àźšàŻ‡àźźàźżàź•àŻàź•àŻàźźàŻ àźȘàŻ‹àź€àŻ àźȘàźżàźŽàŻˆ àźàź±àŻàźȘàźŸàŻàźŸàź€àŻ. àź€àźŻàź”àŻàźšàŻ†àźŻàŻàź€àŻ àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àźźàŻàźŻàź±àŻàźšàźż àźšàŻ†àźŻàŻàź•.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àźźàŻ†àźšàŻ‡àźœàŻ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àźźàŻ‡àźČàŻàźźàŻ àźžàŻàźŸàŻˆàźČàŻàź•àźłàŻ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àźźàŻ€àźŸàŻàźŸàźźàŻˆàź•àŻàź•", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àźźàŻàźŸàźżàźšàŻàź€àź€àŻ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "àźȘàźŻàź©àź°àŻàźȘàŻ†àźŻàź°àŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻ àźšàźżàź±àźźàŻ, {index,number} / {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àź‰àź™àŻàź•àźłàŻ QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻàźŸàŻˆ àźźàŻ€àźŸàŻàźŸàźźàŻˆàź€àŻàź€àźŸàźČàŻ, àź‰àź™àŻàź•àźłàŻ àź€àź±àŻàźȘàŻ‹àź€àŻˆàźŻ QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻ àźźàź±àŻàź±àŻàźźàŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻ àź‡àź©àźż àź’àź°àŻàźȘàŻ‹àź€àŻàźźàŻ àź”àŻ‡àźČàŻˆ àźšàŻ†àźŻàŻàźŻàźŸàź€àŻ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àź‡àźŁàŻˆàźȘàŻàźȘàŻˆ àźźàŻ€àźŸàŻàźŸàźźàŻˆàź•àŻàź•àźżàź±àź€àŻ...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR àź•àŻàź±àźżàźŻàŻ€àźŸàŻ àźźàź±àŻàź±àŻàźźàŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻ àź…àźźàŻˆàź•àŻàź•àźȘàŻàźȘàźŸàź”àźżàźČàŻàźČàŻˆ. àź‰àź™àŻàź•àźłàŻ àźšàŻ†àźŸàŻàź”àŻŠàź°àŻàź•àŻ àź‡àźŁàŻˆàźȘàŻàźȘàŻˆàźšàŻ àźšàź°àźżàźȘàźŸàź°àŻàź€àŻàź€àŻ, àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àźźàŻàźŻàźČàź”àŻàźźàŻ.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àź‰àź™àŻàź•àźłàŻ Signal àźȘàźŻàź©àź°àŻ àźȘàŻ†àźŻàź°àŻˆ àź…àźźàŻˆàź•àŻàź•àź”àŻàźźàŻ", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "àźźàŻ€àźŁàŻàźŸàŻàźźàŻ àź…àź©àŻàźȘàŻàźȘàŻàź•", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àźźàŻ‡àźČàŻàźźàŻ àźšàŻ†àźŻàźČàŻàź•àźłàŻ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻàź•àźłàŻ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àźȘàŻàź€àźżàźŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àźȘàŻàź€àźżàźŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àźźàŻ‡àźČàŻàźźàŻ àźšàŻ†àźŻàźČàŻàź•àźłàŻ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻ àź”àź°àźČàźŸàź±àŻàź±àŻˆ àź…àźŽàźżàź•àŻàź•àź”àŻàźźàŻ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻ àź”àź°àźČàźŸàź±àŻàź±àŻˆ àź…àźŽàźżàź•àŻàź• àź”àŻ‡àźŁàŻàźŸàŻàźźàźŸ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àź‡àź€àŻ àź…àź©àŻˆàź€àŻàź€àŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ àź”àź°àźČàźŸàź±àŻàź±àŻˆàźŻàŻàźźàŻ àźšàźżàź°àźšàŻàź€àź°àźźàźŸàź• àźšàŻ€àź•àŻàź•àŻàźźàŻ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àź…àźŽàźż", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àź…àźŽàŻˆàźȘàŻàźȘàŻ àź”àź°àźČàźŸàź±àŻ àź…àźŽàźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź€àŻ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àźȘàźŸàź°àŻàź•àŻàź• àź…àźČàŻàźČàź€àŻ àź…àźŽàŻˆàźȘàŻàźȘàŻˆàź€àŻ àź€àŻŠàźŸàź™àŻàź• àź•àźżàźłàźżàź•àŻ àźšàŻ†àźŻàŻàźŻàź”àŻàźźàŻ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àź€àŻ‡àźŸàźČàŻ", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àź€àź”àź±àź”àźżàźŸàŻàźŸàź”àŻˆ àź…àźŸàźżàźȘàŻàźȘàźŸàŻˆàźŻàźżàźČàŻ àź”àźŸàźżàź•àźŸàŻàźŸàŻ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àźšàźżàźČàŻˆàźźàźŸàź±àŻàź±àŻ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àźšàźźàŻ€àźȘàź€àŻàź€àźżàźŻ àź…àźŽàŻˆàźȘàŻàźȘàŻàź•àźłàŻ àź‡àźČàŻàźČàŻˆ. àź’àź°àŻ àźšàźŁàŻàźȘàź°àŻàź•àŻàź•àŻ àźšàŻ†àźŻàŻàź€àźż àź…àź©àŻàźȘàŻàźȘàŻàź”àź€àź©àŻ àźźàŻ‚àźČàźźàŻ àź€àŻŠàźŸàź™àŻàź•àź”àŻàźźàŻ.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "''{query}' àź•àŻàź•àźŸàź© àźźàŻàźŸàźżàź”àŻàź•àźłàŻ àźŽàź€àŻàź”àŻàźźàŻ àź•àźżàźŸàŻˆàź•àŻàź•àź”àźżàźČàŻàźČàŻˆ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àź‰àźłàŻàź”àź°àŻàźźàŻ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àź…àź”àŻàźŸàŻàź•àŻ‹àźŻàźżàź™àŻ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àź€àź”àź±àź”àźżàźŸàŻàźŸàź”àŻˆ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àźšàźźàŻ€àźȘàź€àŻàź€àźżàźŻ àź‰àź°àŻˆàźŻàźŸàźŸàźČàŻàź•àźłàŻ àźŽàź€àŻàź”àŻàźźàźżàźČàŻàźČàŻˆ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "''{query}' àź•àŻàź•àźŸàź© àźźàŻàźŸàźżàź”àŻàź•àźłàŻ àźŽàź€àŻàź”àŻàźźàŻ àź•àźżàźŸàŻˆàź•àŻàź•àź”àźżàźČàŻàźČàŻˆ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àź”àŻ†àźłàźżàźšàŻàźšàŻ†àźČàŻàźČàŻàźźàŻ àź•àŻàź°àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àź‰àźłàŻàź”àź°àŻàźźàŻ àź•àŻàź°àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ}}} Video {{direction, select, Outgoing {àź”àŻ†àźłàźżàźšàŻàźšàŻ†àźČàŻàźČàŻàźźàŻ àź•àźŸàźŁàŻ†àźŸàźłàźż àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àź‰àźłàŻàź”àź°àŻàźźàŻ àź•àźŸàźŁàŻ†àźŸàźłàźż àź…àźŽàŻˆàźȘàŻàźȘàŻ}}} Group {{direction, select, Outgoing {àź”àŻ†àźłàźżàźšàŻàźšàŻ†àźČàŻàźČàŻàźźàŻ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àź‰àźłàŻàź”àź°àŻàźźàŻ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ}}} other {{direction, select, Outgoing {àź”àŻ†àźłàźżàźšàŻ†àźČàŻàźČàŻàźźàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àź‰àźłàŻàź”àź°àŻàźźàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àź€àź”àź±àź”àźżàźŸàŻàźŸ àź•àŻàź°àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} Video {àź•àźŸàźŁàŻ†àźŸàźłàźż àź…àźŽàŻˆàźȘàŻàźȘàŻ àź€àź”àź±àź”àźżàźŸàŻàźŸàź€àŻ} Group {àź€àź”àź±àźżàźŻ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àź€àź”àź±àźżàźŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àźȘàź€àźżàźČàźłàźżàź•àŻàź•àźȘàŻàźȘàźŸàźŸàź€ àź•àŻàź°àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} Video {àźȘàź€àźżàźČàźłàźżàź•àŻàź•àźȘàŻàźȘàźŸàźŸàź€ àź•àźŸàźŁàŻ†àźŸàźłàźż àź…àźŽàŻˆàźȘàŻàźȘàŻ} Group {àźȘàź€àźżàźČàźłàźżàź•àŻàź•àźȘàŻàźȘàźŸàźŸàź€ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àźȘàź€àźżàźČàźłàźżàź•àŻàź•àźȘàŻàźȘàźŸàźŸàź€ àź…àźŽàŻˆàźȘàŻàźȘàŻ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àźšàźżàź°àźŸàź•àź°àźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸ àź•àŻàź°àźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} Video {àźšàźżàź°àźŸàź•àź°àźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸ àź”àŻ€àźŸàźżàźŻàŻ‹ àź…àźŽàŻˆàźȘàŻàźȘàŻ} Group {àźšàźżàź°àźŸàź•àź°àźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ} other {àźšàźżàź°àźŸàź•àź°àźżàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸ àź…àźŽàŻˆàźȘàŻàźȘàŻ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {àźźàŻ‡àźČàŻàźźàŻ {count,number} àźšàźȘàź°àŻ àźŸàŻˆàźȘàŻ àźšàŻ†àźŻàŻàź•àźżàź±àźŸàź°àŻ.} other {àźźàŻ‡àźČàŻàźźàŻ {count,number} àźȘàŻ‡àź°àŻ àźŸàŻˆàźȘàŻ àźšàŻ†àźŻàŻàź•àźżàź©àŻàź±àź©àź°àŻ.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àźȘàŻàź€àźżàź€àźŸàź• àźŽàź©àŻàź© àź‰àźłàŻàźłàź€àŻ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àźšàźżàź±àŻ àźźàźŸàź±àŻàź±àź™àŻàź•àźłàŻ, àźȘàźżàźŽàŻˆ àź€àźżàź°àŻàź€àŻàź€àź™àŻàź•àźłàŻ àźźàź±àŻàź±àŻàźźàŻ àźšàŻ†àźŻàźČàŻàź€àźżàź±àź©àŻ àźźàŻ‡àźźàŻàźȘàźŸàźŸàŻàź•àźłàŻ. àźšàźżàź•àŻàź©àźČàŻˆàźȘàŻ àźȘàźŻàź©àŻàźȘàźŸàŻàź€àŻàź€àźżàźŻàź€àź±àŻàź•àŻ àźšàź©àŻàź±àźż!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àź‡àźšàŻàź€ àźȘàŻàź€àŻàźȘàŻàźȘàźżàźȘàŻàźȘàźżàźČàŻ àź•àŻàź°àźČàŻ àźźàź±àŻàź±àŻàźźàŻ àź”àŻ€àźŸàźżàźŻàŻ‹ àź…àźŽàŻˆàźȘàŻàźȘàŻàź•àźłàŻàź•àŻàź•àźŸàź© àźšàźżàźČ àźźàŻ‡àźźàŻàźȘàźŸàźŸàŻàź•àźłàŻ àźźàź±àŻàź±àŻàźźàŻ àźšàźżàźČ àźšàźżàź±àźżàźŻ àź†àź”àźŁàźȘàŻ àźȘàŻàź€àŻàźȘàŻàźȘàźżàźȘàŻàźȘàŻàź•àźłàŻ àź†àź•àźżàźŻàź”àŻˆ àź…àźŸàź™àŻàź•àŻàźźàŻ (àźšàź©àŻàź±àźż, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "àź‡àźȘàŻàźȘàŻ‹àź€àŻ àź‰àź™àŻàź•àźłàŻ àźšàźżàźžàŻàźŸàźźàŻ àź…àźźàŻˆàźȘàŻàźȘàŻàź•àźłàŻˆ àźźàźŸàź±àŻàź±àźŸàźźàźČàŻ‡àźŻàŻ‡ àźšàŻ€àź™àŻàź•àźłàŻ àź€àŻ‡àź°àŻàźšàŻàź€àŻ†àźŸàŻàź€àŻàź€ àźźàŻŠàźŽàźżàźŻàŻˆ Signal àź‡àźČàŻ àźźàźŸàź±àŻàź±àźČàźŸàźźàŻ (Signal àź…àźźàŻˆàźȘàŻàźȘàŻàź•àźłàŻ > àź€àŻ‹àź±àŻàź±àźźàŻ > àźźàŻŠàźŽàźż)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àźȘàŻàź€àźżàź€àźŸàź• àźŻàźŸàź°àźŸàź”àź€àŻ àź•àŻàźŽàŻàź”àźżàźČàŻ àźšàŻ‡àź°àŻàźźàŻàźȘàŻ‹àź€àŻ, àź•àŻàźŽàŻ àźȘàŻàź€àŻàźȘàŻàźȘàźżàźȘàŻàźȘàŻàź•àźłàŻàź•àŻàź•àŻàź€àŻ àź€àŻ‹àź©àŻàź±àŻàźźàŻ àź…àź±àźżàź”àźżàźȘàŻàźȘàŻ àźàź•àźŸàź©àŻàź•àźłàŻˆ àźšàźŸàź™àŻàź•àźłàŻ àźźàźŸàź±àŻàź±àźżàźŻàźźàŻˆàź€àŻàź€àŻàźłàŻàźłàŻ‹àźźàŻ. àź•àŻàź±àźżàźȘàŻàźȘàźŸàź• àźšàŻ€àź™àŻàź•àźłàŻ àźŸàźŸàź°àŻàź•àŻ àź€àŻ€àźźàŻ àźȘàźŻàź©àŻàźȘàźŸàŻàź€àźżàź©àźŸàźČàŻ, àź‡àźšàŻàź€ àźàź•àźŸàź©àŻàź•àźłàŻ àź€àŻ†àźłàźżàź”àŻàź€àŻàź€àźżàź±àź©àŻˆ àźźàŻ‡àźźàŻàźȘàźŸàŻàź€àŻàź€ àź‰àź€àź”àŻàź•àźżàź©àŻàź±àź©. àźźàŻàźšàŻàź€àŻˆàźŻ àźàź•àźŸàź©àŻàź•àźłàŻ àźŸàźŸàź°àŻàź•àŻ àź€àŻ€àźźàŻ-àź àźàź±àŻàź±àŻàź•àŻàź•àŻŠàźŁàŻàźŸàź©. àźȘàŻàź€àźżàźŻ àźàź•àźŸàź©àŻàź•àźłàŻ àź…àź€àźżàźČàŻ àź‰àź°àŻàź”àŻ†àźŸàŻàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź”àŻˆ, àź…àź€àźżàźČàŻ àź”àźŸàźżàź”àźźàŻˆàź•àŻàź•àźȘàŻàźȘàźŸàŻàźŸàź”àŻˆ." + "icu:WhatsNew__v6.39--1": { + "messageformat": "àźšàźżàźČ àźšàźźàźŻàź™àŻàź•àźłàźżàźČàŻ macOS àźšàźŸàź€àź©àź™àŻàź•àźłàźżàźČàŻ àź…àźŽàŻˆàźȘàŻàźȘàŻ àźČàźŸàźȘàźżàźŻàźżàźČàŻ àźšàŻ‡àź°àŻàźźàŻàźȘàŻ‹àź€àŻ àźàź±àŻàźȘàźŸàŻàźźàŻ àź’àź°àŻ àźšàźżàź±àźżàźŻ àź€àźŸàźźàź€àź€àŻàź€àŻˆ àźšàźŸàź™àŻàź•àźłàŻ àźšàź°àźż àźšàŻ†àźŻàŻàź€àŻ àź”àźżàźŸàŻàźŸàŻ‹àźźàŻ." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àźŻàźŸàź°àźŸàź”àź€àŻ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàźżàźČàŻ àźšàŻ‡àź°àŻàźźàŻàźȘàŻ‹àź€àŻ àź…àźČàŻàźČàź€àŻ àź”àŻ†àźłàźżàźŻàŻ‡àź±àŻàźźàŻàźȘàŻ‹àź€àŻ àź”àŻ€àźŸàźżàźŻàŻ‹ àźŸàŻˆàźČàŻàź•àźłàŻàź•àŻàź•àźŸàź© àźŸàźżàź°àźŸàź©àŻàźšàźżàź·àź©àŻ àź…àź©àźżàźźàŻ‡àź·àź©àŻˆ àźšàźŸàź™àŻàź•àźłàŻ àźšàź°àźżàźšàŻ†àźŻàŻàź€àŻàźłàŻàźłàŻ‹àźźàŻ. àźŻàźŸàź°àźŸàź”àź€àŻ àź•àŻàźŽàŻ àź…àźŽàŻˆàźȘàŻàźȘàźżàźČàŻ àźšàŻ‡àź°àŻàźźàŻàźȘàŻ‹àź€àŻ àź…àźČàŻàźČàź€àŻ àź”àŻ†àźłàźżàźŻàŻ‡àź±àŻàźźàŻàźȘàŻ‹àź€àŻ àź”àŻ€àźŸàźżàźŻàŻ‹ àźŸàŻˆàźČàŻàź•àźłàŻàź•àŻàź•àźŸàź© àźŸàźżàź°àźŸàź©àŻàźšàźżàź·àź©àŻ àź…àź©àźżàźźàŻ‡àź·àź©àŻˆ àźšàźŸàź™àŻàź•àźłàŻ àźšàź°àźżàźšàŻ†àźŻàŻàź€àŻàźłàŻàźłàŻ‹àźźàŻ." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àźšàźŸàźŸàŻ àź…àźźàŻˆàźȘàŻàźȘàŻàź•àźłàŻˆ àź”àźżàź°àŻˆàź”àźŸàź• àź…àźŁàŻàź• àź…àźČàŻàźČàź€àŻ àź…àźšàŻàź€ àźšàźŸàźŸàŻàźŸàźżàźČàŻ àź‡àź°àŻàźšàŻàź€àŻ àźȘàźŸàź°àŻàź•àŻàź•àźȘàŻàźȘàźŸàźŸàź€ àźžàŻàźŸàŻ‹àź°àŻ€àźžàŻˆàźȘàŻ àźȘàźŸàź°àŻàź•àŻàź•, àźšàźŸàźŸàŻ àźźàŻàź•àźȘàŻàźȘàźżàźČàŻ àź‰àźłàŻàźł àźȘàŻàź°àŻŠàźƒàźȘàŻˆàźČàŻ àźȘàŻàź•àŻˆàźȘàŻàźȘàźŸàźźàŻ àź…àźČàŻàźČàź€àŻ àź•àŻàźŽàŻ àźȘàŻàź•àŻˆàźȘàŻàźȘàźŸàź€àŻàź€àŻˆàź•àŻ àź•àŻàźłàźżàź•àŻ àźšàŻ†àźŻàŻàźŻàźČàźŸàźźàŻ. àźšàź©àŻàź±àźż, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/te-IN/messages.json b/_locales/te-IN/messages.json index 4ad4788c50..f3cbbbe692 100644 --- a/_locales/te-IN/messages.json +++ b/_locales/te-IN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "à°Šà°€à±à°€à°Ÿà°‚à°¶à°źà±‚à°Č à°Čోà°Șం", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "à°Ąà±‡à°Ÿà°Ÿà°Źà±‡à°žà± à°Čోà°Șం ఏర్à°Șà°Ąà°żà°‚à°Šà°ż. à°źà±€à°°à± à°Čోà°Șà°Ÿà°šà±à°šà°ż à°•à°Ÿà°Șీ à°šà±‡à°žà°ż, à°žà°źà°žà±à°Żà°šà± à°Șà°°à°żà°·à±à°•à°°à°żà°‚à°šà°Ąà°‚à°Čో à°žà°čà°Ÿà°Żà°Șà°Ąà°Ÿà°Ÿà°šà°żà°•à°ż Signal à°źà°Šà±à°Šà°€à±à°šà± à°žà°‚à°Șà±à°°à°Šà°żà°‚à°šà°”à°šà±à°šà±. à°’à°•à°”à±‡à°ł à°źà±€à°°à± Signal చు à°€à°•à±à°·à°Łà°źà±‡ ఉà°Șà°Żà±‹à°—à°żà°‚à°šà°”à°Čà°žà°ż ఔఞ్ఀే, à°źà±€à°°à± à°źà±€ à°Ąà±‡à°Ÿà°Ÿà°šà± ఀొà°Čà°—à°żà°‚à°šà°ż, రీఞ్టటర్ట్ à°šà±‡à°Żà°”à°šà±à°šà±.\n\nఈ à°Čà°żà°‚à°•à±â€Œà°šà± à°žà°‚à°Šà°°à±à°¶à°żà°‚à°šà°Ąà°‚ ఊ్ఔటరట à°źà°Šà±à°Šà°€à±à°šà± à°žà°‚à°Șà±à°°à°Šà°żà°‚à°šà°‚à°Ąà°ż: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "à°źà±Šà°€à±à°€à°‚ à°žà°źà°Ÿà°šà°Ÿà°°à°źà±à°šà± ఀొà°Čà°—à°żà°‚à°šà°ż à°Șుచఃà°Șà±à°°à°Ÿà°°à°‚à°­à°żà°‚à°šà°‚à°Ąà°ż", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "à°Ąà±‡à°Ÿà°Ÿà°šà± ఀొà°Čà°—à°żà°‚à°šà°ż, రీఞ్టటర్ట్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "à°źà±Šà°€à±à°€à°‚ à°Ąà±‡à°Ÿà°Ÿà°šà± శటశ్ఔఀంగట ఀొà°Čà°—à°żà°‚à°šà±‡à°Šà°Ÿ?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "à°źà±€ à°źà±Šà°€à±à°€à°‚ ఞంఊేశ à°šà°°à°żà°€à±à°° à°źà°°à°żà°Żà± à°źà±€à°Ąà°żà°Żà°Ÿ ఈ à°Șà°°à°żà°•à°°à°‚ à°šà±à°‚à°Ąà°ż శటశ్ఔఀంగట ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà°€à°Ÿà°Żà°ż. Signal చు à°źà°łà±à°łà±€ à°Čà°żà°‚à°•à± à°šà±‡à°žà°żà°š ఀర్ఔటఀ à°źà±€à°°à± ఈ à°Șà°°à°żà°•à°°à°‚à°Čో à°Šà°Ÿà°šà±à°šà°ż ఉà°Șà°Żà±‹à°—à°żà°‚à°šà°—à°Čుగుఀటరు. à°Šà±€à°šà°ż à°”à°Čà°š à°źà±€ ఫోచ్ à°šà±à°‚à°Ąà°ż à°Ąà±‡à°Ÿà°Ÿ ఏఊీ ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà°Šà±.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "à°źà±€ à°Ąà±‡à°Ÿà°Ÿà°Źà±‡à°žà± à°Żà±Šà°•à±à°• ఔెర్షచ్ Signal à°Żà±Šà°•à±à°• ఈ ఔెర్షచ్‌ఀో à°žà°°à°żà°Șోà°Čà°Ąà°‚ à°Čేఊు. à°źà±€à°°à± à°źà±€ కంà°Șà±à°Żà±‚à°Ÿà°°à±à°Čో Signal à°Żà±Šà°•à±à°• ఀటజట ఔెర్షచ్‌చు à°€à±†à°°à±à°žà±à°€à±à°šà±à°šà°Ÿà°°à°šà°ż à°šà°żà°°à±à°§à°Ÿà°°à°żà°‚à°šà±à°•à±‹à°‚à°Ąà°ż.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&à°Șà°‚à°•à±à°€à°ż", @@ -300,6 +316,70 @@ "messageformat": "చటట్ఞ్", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "à°źà±€ à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°€à±‹ ఏఊో à°€à°Ș్à°Șు à°œà°°à°żà°—à°żà°‚à°Šà°ż, à°‡à°Šà°ż à°źà±€ ఖటఀటకు ఇక à°à°źà°Ÿà°€à±à°°à°‚ à°•à±‡à°Ÿà°Ÿà°Żà°żà°‚à°šà°Źà°Ąà°Čేఊు. à°źà±€à°°à± à°Șà±à°°à°Żà°€à±à°šà°żà°‚à°šà°ż, à°Šà°Ÿà°šà°żà°šà°ż à°źà°łà±à°łà±€ ఞెట్ à°šà±‡à°Żà°”à°šà±à°šà± à°Čేఊట ఒక కొఀ్ఀ à°Šà°Ÿà°šà°żà°šà°ż ఎంచుకోఔచ్చు.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ఇà°Ș్à°Șà±à°Ąà± à°Șà°°à°żà°·à±à°•à°°à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "à°źà±€ QR à°•à±‹à°Ąà± à°źà°°à°żà°Żà± à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà± à°Čà°żà°‚à°•à±â€Œà°€à±‹ ఏఊో à°€à°Ș్à°Șు à°œà°°à°żà°—à°żà°‚à°Šà°ż, à°‡à°Šà°ż ఇకà°Șై చెà°Č్à°Čà±à°Źà°Ÿà°Ÿà± కటఊు. ఇఀరుà°Čఀో à°Șà°‚à°šà±à°•à±‹à°”à°Ąà°Ÿà°šà°żà°•à°ż కొఀ్ఀ à°Čà°żà°‚à°•à±â€Œà°šà± à°žà±ƒà°·à±à°Ÿà°żà°‚à°šà°‚à°Ąà°ż.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ఇà°Ș్à°Șà±à°Ąà± à°Șà°°à°żà°·à±à°•à°°à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "à°Ÿà±à°Żà°Ÿà°Źà±â€Œà°Čచు చూà°Șà°‚à°Ąà°ż", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "à°Ÿà±à°Żà°Ÿà°Źà±â€Œà°Čచు à°Šà°Ÿà°Żà°‚à°Ąà°ż", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ఒక à°Čోà°Șం ఏర్à°Șà°Ąà°żà°‚à°Šà°ż", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} à°šà°Šà°”à°šà°żà°”à°ż à°‰à°šà±à°šà°Ÿà°Żà°ż", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "à°šà°Šà°”à°šà°żà°”à°ż à°źà°Ÿà°°à±à°•à± à°šà±‡à°Żà°Źà°Ąà±à°Ąà°Ÿà°Żà°ż", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "చటట్ఞ్", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "à°•à°Ÿà°Č్ఞ్", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "à°•à°„à°Čు", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "à°…à°źà°°à°żà°•à°Čు", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal చు à°šà°”à±€à°•à°°à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "à°”à±à°Żà°•à±à°€à°żà°€à±à°”à°”à°°à±à°Łà°š", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "à°€à°żà°°à°żà°—à°ż", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ఈ చటట్ఞ్ ఆర్కైఔ్ à°šà±‡à°Żà°Źà°Ąà±à°Ąà°Ÿà°Żà°ż à°źà°°à°żà°Żà± à°’à°•à°”à±‡à°ł క్రొఀ్ఀ ఞంఊేశటà°Čు అంఊుకుచ్చà°Ș్à°Șà±à°Ąà± à°źà°Ÿà°€à±à°°à°źà±‡ à°‡à°šà±â€Œà°Źà°Ÿà°•à±à°žà±â€Œà°Čో à°•à°šà°żà°Șà°żà°žà±à°€à°Ÿà°Żà°ż.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "à°à°źà±ˆà°šà°Ÿ à°•à°Ÿà°Č్ à°šà±‡à°Żà°‚à°Ąà°ż", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "à°à°Šà±‡à°źà±ˆà°šà°Ÿ à°šà±‡à°°à°‚à°Ąà°ż", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "à°•à°Ÿà°Č్ à°•à±Šà°šà°žà°Ÿà°—à°żà°‚à°šà°‚à°Ąà°ż", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "భఊ్రఀట à°žà°‚à°–à±à°Żà°Čు అà°Șà±â€Œà°Ąà±‡à°Ÿà± à°šà±‡à°Żà°Źà°Ąà±à°€à±à°šà±à°šà°Ÿà°Żà°ż.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ఇంకట చేర్చుకో", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "à°źà±à°šà±à°Șà°Ÿà°ż భఊ్రఀట à°žà°‚à°–à±à°Ż", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ఀఊుà°Șà°°à°ż భఊ్రఀట à°žà°‚à°–à±à°Ż", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "భఊ్రఀట à°žà°‚à°–à±à°Ż ఔెర్షచ్, {total,number} à°Čో {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "à°§à±ƒà°”à±€à°•à°°à°żà°‚à°šà°Źà°Ąà°żà°šà°Ÿà±à°Čు గుర్ఀు à°Șà±†à°Ÿà±à°Ÿà°‚à°Ąà°ż", @@ -663,33 +747,41 @@ "messageformat": "à°§à±ƒà°”à±€à°•à°°à°Łà°šà± క్à°Čà°żà°Żà°°à± à°šà±‡à°Żà°‚à°Ąà°ż", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name}‌ఀో à°Șà±‚à°°à±à°€à°ż à°žà±à°„à°Ÿà°Żà°ż à°Žà°šà±â€Œà°•à±à°°à°żà°Ș్షచ్‌చు à°§à±ƒà°”à±€à°•à°°à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż, à°Șైచ ఉచ్చ à°žà°‚à°–à±à°Żà°Čచు à°”à°Ÿà°Ÿà°ż à°Șà°°à°żà°•à°°à°‚à°€à±‹ à°Șోà°Čà±à°šà°‚à°Ąà°ż. ఔటరు à°źà±€ à°•à±‹à°Ąà±â€Œà°šà± à°”à°Ÿà°°à°ż à°Șà°°à°żà°•à°°à°‚à°€à±‹ à°•à±‚à°Ąà°Ÿ ఞ్కటచ్ à°šà±‡à°Żà°”à°šà±à°šà±.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "à°źà°°à°żà°‚à°€ à°šà±‡à°°à±à°šà±à°•à±‹à°‚à°Ąà°ż", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name}‌ఀో à°Șà±‚à°°à±à°€à°ż à°žà±à°„à°Ÿà°Żà°ż à°Žà°šà±â€Œà°•à±à°°à°żà°Ș్షచ్‌చు à°§à±ƒà°”à±€à°•à°°à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż, à°Șైచ ఉచ్చ రంగు à°•à°Ÿà°°à±à°Ąà±à°šà± à°”à°Ÿà°°à°ż à°Șà°°à°żà°•à°°à°‚à°€à±‹ à°źà±à°Żà°Ÿà°šà± à°šà±‡à°Żà°‚à°Ąà°ż à°źà°°à°żà°Żà± à°žà°‚à°–à±à°Żà°Čచు à°Șోà°Čà±à°šà°‚à°Ąà°ż. à°’à°•à°”à±‡à°ł à°‡à°”à°ż à°źà±à°Żà°Ÿà°šà± à°•à°Ÿà°•à°Șోఀే, భఊ్రఀట à°žà°‚à°–à±à°Żà°Č à°źà°°à±‹ జఀచు à°Șà±à°°à°Żà°€à±à°šà°żà°‚à°šà°‚à°Ąà°ż. కేఔà°Čం ఒక జఀ à°źà°Ÿà°€à±à°°à°źà±‡ à°źà±à°Żà°Ÿà°šà± కటఔటà°Čà°ż.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name}‌ఀో à°Șà±‚à°°à±à°€à°ż à°žà±à°„à°Ÿà°Żà°ż à°Žà°šà±â€Œà°•à±à°°à°żà°Ș్షచ్‌చు à°§à±ƒà°”à±€à°•à°°à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż, à°Șైచ ఉచ్చ à°žà°‚à°–à±à°Żà°Čచు à°”à°Ÿà°Ÿà°ż à°Șà°°à°żà°•à°°à°‚à°€à±‹ à°Șోà°Čà±à°šà°‚à°Ąà°ż. ఔటరు à°źà±€ à°•à±‹à°Ąà±â€Œà°šà± à°”à°Ÿà°°à°ż à°Șà°°à°żà°•à°°à°‚à°€à±‹ à°•à±‚à°Ąà°Ÿ ఞ్కటచ్ à°šà±‡à°Żà°”à°šà±à°šà±.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "భఊ్రఀట à°žà°‚à°–à±à°Żà°Čకు à°źà°Ÿà°°à±à°Șుà°Čు", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal à°Čో à°°à°Ÿà°Źà±‹à°Żà±‡ గోà°Șà±à°Żà°€à°Ÿ à°”à°żà°Čà°•à±à°·à°Łà°€à°Čచు à°Șà±à°°à°Ÿà°°à°‚à°­à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż à°Șà°°à°żà°”à°°à±à°€à°š à°”à±à°Żà°”à°§à°żà°Čో భఊ్రఀట à°žà°‚à°–à±à°Żà°Čు అà°Șà±â€Œà°Ąà±‡à°Ÿà± à°šà±‡à°Żà°Źà°Ąà±à°€à±à°šà±à°šà°Ÿà°Żà°ż.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "భఊ్రఀట à°žà°‚à°–à±à°Żà°Čచు à°§à±ƒà°”à±€à°•à°°à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż, à°źà±€ కటంటటక్ట్ à°Żà±Šà°•à±à°• à°Șà°°à°żà°•à°°à°‚à°€à±‹ రంగు à°•à°Ÿà°°à±à°Ąà±à°šà± à°źà±à°Żà°Ÿà°šà± à°šà±‡à°Żà°‚à°Ąà°ż. à°’à°•à°”à±‡à°ł à°‡à°”à°ż à°źà±à°Żà°Ÿà°šà± à°•à°Ÿà°•à°Șోఀే, భఊ్రఀట à°žà°‚à°–à±à°Żà°Č à°źà°°à±‹ జఀచు à°Șà±à°°à°Żà°€à±à°šà°żà°‚à°šà°‚à°Ąà°ż. కేఔà°Čం ఒక జఀ à°źà°Ÿà°€à±à°°à°źà±‡ à°źà±à°Żà°Ÿà°šà± కటఔటà°Čà°ż.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "à°žà°Ÿà°Żà°‚ à°…à°”à°žà°°à°źà°Ÿ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "à°…à°°à±à°„à°źà±ˆà°‚à°Šà°ż", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "à°źà±€à°°à± ఈ à°”à±à°Żà°•à±à°€à°żà°€à±‹ ఞంఊేశటà°Čచు à°źà°Ÿà°°à±à°Șà°żà°Ąà°ż à°šà±‡à°žà°żà°š ఀర్ఔటఀ à°”à°Ÿà°°à°żà°€à±‹ భఊ్రఀట à°žà°‚à°–à±à°Ż à°žà±ƒà°·à±à°Ÿà°żà°‚à°šà°Źà°Ąà±à°€à±à°‚à°Šà°ż.", @@ -1267,10 +1359,6 @@ "messageformat": "ఇటీఔà°Čà°ż à°źà±€à°Ąà°żà°Żà°Ÿà°šà± à°šà±‚à°Ąà°‚à°Ąà°ż", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name}‌ఀో à°źà±€ à°Șà±‚à°°à±à°€à°ż à°žà±à°„à°Ÿà°Żà°ż à°Žà°šà±â€Œà°•à±à°°à°żà°Ș్షచ్ à°Żà±Šà°•à±à°• భఊ్రఀచు à°§à±ƒà°”à±€à°•à°°à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż, à°Șైచ ఉచ్చ à°žà°‚à°–à±à°Żà°Čచు à°”à°Ÿà°°à°ż à°Șà°°à°żà°•à°°à°‚à°€à±‹ à°Șోà°Čà±à°šà°‚à°Ąà°ż. à°Șైచ ఉచ్చ qr à°•à±‹à°Ąà±â€Œà°šà± à°•à±‚à°Ąà°Ÿ ఔటరు ఞ్కటచ్ à°šà±‡à°Żà°”à°šà±à°šà±.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ఈ à°Șà°°à°żà°šà°Żà°‚à°€à±‹ à°źà±€à°°à± ఇంకట ఞంఊేశటà°Čచు à°źà°Ÿà°°à±à°Șà°żà°Ąà°ż à°šà±‡à°Żà°Čేఊు. à°”à°Ÿà°°à°żà°€à±‹ à°źà±€ భఊ్రఀట à°žà°‚à°–à±à°Ż à°źà±Šà°Šà°Ÿà°ż ఞంఊేశం ఀర్ఔటఀ à°…à°‚à°Šà±à°Źà°Ÿà°Ÿà±à°Čో à°‰à°‚à°Ÿà±à°‚à°Šà°ż." }, @@ -1334,17 +1422,17 @@ "messageformat": "à°žà°źà°Ÿà°šà°Ÿà°°à°‚", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ఀొà°Čà°—à°żà°‚à°šà°‚à°Ąà°ż", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ఞంఊేశటà°Čచు ఀొà°Čà°—à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "చటట్ ఀొà°Čà°—à°żà°‚à°šà±‡à°Šà°Ÿ?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ఞంఊేశటà°Čచు ఀొà°Čà°—à°żà°‚à°šà±‡à°Šà°Ÿ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ఈ à°Șà°°à°żà°•à°°à°‚ à°šà±à°‚à°Ąà°ż ఈ చటట్ ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà±à°€à±à°‚à°Šà°ż.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ఈ à°Șà°°à°żà°•à°°à°‚ à°šà±à°‚à°Ąà°ż ఈ చటట్‌à°Čà±‹à°šà°ż ఞంఊేశటà°Čు ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà°€à°Ÿà°Żà°ż. à°źà±€à°°à± ఞంఊేశటà°Čచు ఀొà°Čà°—à°żà°‚à°šà°żà°š ఀర్ఔటఀ à°•à±‚à°Ąà°Ÿ à°źà±€à°°à± ఇంకట ఈ చటట్ కోఞం à°¶à±‹à°§à°żà°‚à°šà°”à°šà±à°šà±.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "గ్రూà°Ș్‌చు à°”à°Šà°żà°Čà±‡à°Żà°‚à°Ąà°ż", @@ -1438,6 +1526,14 @@ "messageformat": "à°°à±†à°‚à°Ąà± చటట్‌à°Č కొరకు à°źà±€ ఞంఊేశ à°šà°°à°żà°€à±à°° à°‡à°•à±à°•à°Ą కà°Čà°żà°Șà°ż à°”à±‡à°Żà°Źà°Ąà°żà°‚à°Šà°ż.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} కు à°šà±†à°‚à°Šà°żà°šà°Šà°ż. à°źà±€à°°à± {sharedGroup} à°°à±†à°‚à°Ąà°żà°‚à°Ÿà°ż à°žà°­à±à°Żà±à°Čు.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} కు à°šà±†à°‚à°Šà°żà°šà°Šà°ż", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "కోట్ à°šà±‡à°žà°żà°š ఞంఊేశం à°šà±à°‚à°Ąà°ż à°šà°żà°€à±à°°à°‚ à°Żà±Šà°•à±à°• à°žà±‚à°•à±à°·à±à°źà°šà°żà°€à±à°°à°‚", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "à°źà°łà±à°łà±€ à°•à°Ÿà°Č్ à°šà±‡à°Żà°‚à°Ąà±€", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "à°•à°Ÿà°Č్ à°Șà±à°°à°Ÿà°°à°‚à°­à°żà°‚à°šà°‚à°Ąà°ż", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "à°•à°Ÿà°Č్‌à°Čో à°šà±‡à°°à°‚à°Ąà°ż", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "à°•à°Ÿà°Č్ à°•à°Ÿà°Č à°”à±à°Żà°”à°§à°ż à°•à°Ÿà°°à°Łà°‚à°—à°Ÿ à°źà±ˆà°•à±à°°à±‹à°«à±‹à°šà± à°źà±à°Żà±‚à°Ÿà± à°šà±‡à°Żà°Źà°Ąà°żà°‚à°Šà°ż", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "à°•à°Ÿà°Č్ à°šà±‹à°Ÿà°żà°«à°żà°•à±‡à°·à°šà±à°Čు", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "à°•à°Ÿà°Č్ à°šà°żà°‚à°Ąà°żà°‚à°Šà°ż", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "à°•à±†à°źà±†à°°à°Ÿ", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "à°šà±‡à°°à°‚à°Ąà°ż", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "à°Șà±à°°à°Ÿà°°à°‚à°­à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "à°•à°Ÿà°Č్ à°šà°żà°‚à°Ąà°żà°Șà±‹à°Żà°żà°‚à°Šà°ż", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "à°•à±†à°źà±†à°°à°Ÿ à°šà°żà°Čà°żà°Șà°żà°”à±‡à°Żà°Źà°Ąà°żà°‚à°Šà°ż", @@ -1621,10 +1725,6 @@ "messageformat": "à°•à±†à°źà±†à°°à°Ÿà°šà± à°†à°°à°‚à°­à°żà°‚à°šà°‚à°Ąà°ż", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "à°źà±à°Żà±‚à°Ÿà±", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "à°źà±ˆà°•à±à°°à±‹à°«à±‹à°šà± à°šà°żà°Čà°żà°Șà°żà°”à±‡à°Żà°Źà°Ąà°żà°‚à°Šà°ż", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "à°źà±ˆà°•à± à°…à°šà±â€Œà°źà±à°Żà±‚à°Ÿà± à°šà±‡à°Żà°‚à°Ąà°ż", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "à°Șà°‚à°šà±à°•à±‹à°‚à°Ąà°ż", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "à°Șà±à°°à°Šà°°à±à°¶à°żà°‚à°šà°Ąà°‚ à°šà°żà°Čà°żà°Șà°żà°”à±‡à°Żà°Źà°Ąà°żà°‚à°Šà°ż", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "à°Șà±à°°à°Šà°°à±à°¶à°żà°‚à°šà°Ąà°‚ à°źà°Ÿà°šà±‡à°Żà°‚à°Ąà°ż", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "à°°à°żà°‚à°—à±", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "à°Șà°Ÿà°Čà±à°—à±Šà°šà±‡à°”à°Ÿà°°à°żà°•à°ż à°°à°żà°‚à°—à± à°šà±‡à°Żà°Ąà°Ÿà°šà°żà°•à°ż గ్రూà°Șు à°šà°Ÿà°Čà°Ÿ à°Șà±†à°Šà±à°Šà°Šà°ż.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "à°°à°żà°‚à°—à°żà°‚à°—à± à°Șà±à°°à°Ÿà°°à°‚à°­à°żà°žà±à°€à±‹à°‚à°Šà°ż", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "à°°à°żà°‚à°—à°żà°‚à°—à± ఆఫ్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "à°°à°żà°‚à°—à°żà°‚à°—à± ఆచ్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "à°źà°°à°żà°šà±à°šà°ż ఎంà°Șà°żà°•à°Čు", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "à°źà±€à°°à±", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "à°źà±€ à°•à±†à°źà±†à°°à°Ÿ ఆఫ్‌à°Čో à°‰à°‚à°Šà°ż", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "భఊ్రఀట à°žà°‚à°–à±à°Żà°šà± à°”à±€à°•à±à°·à°żà°‚à°šà°‚à°Ąà°ż", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ఞంఊేశం", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "భఊ్రఀట à°žà°‚à°–à±à°Żà°šà± à°”à±€à°•à±à°·à°żà°‚à°šà°‚à°Ąà°ż", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ఫోచ్ à°šà±†à°‚à°Źà°°à± à°Șà±Šà°‚à°Šà°Ąà°‚ à°”à°żà°«à°Čà°źà±ˆà°‚à°Šà°ż. à°źà±€ కచెక్షచ్ చెక్ à°šà±‡à°žà°ż, à°źà°łà±à°Čీ à°Șà±à°°à°Żà°€à±à°šà°żà°‚à°šà°‚à°Ąà°ż.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ఈ à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°źà±€à°°à± à°Șంà°Șà°żà°š à°žà°źà°Żà°‚ à°šà±à°‚à°šà°ż 3 గంటà°Čà°Čోà°Șు à°źà°Ÿà°€à±à°°à°źà±‡ à°žà°”à°°à°Łà°Čు à°”à°°à±à°€à°żà°‚à°Șà°œà±‡à°Żà°Źà°Ąà°€à°Ÿà°Żà°ż.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ఈ à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°źà±€à°°à± à°Șంà°Șà°żà°š à°žà°źà°Żà°‚ à°šà±à°‚à°šà°ż 24 గంటà°Čà°Čోà°Șు à°źà°Ÿà°€à±à°°à°źà±‡ à°žà°”à°°à°Łà°Čు à°”à°°à±à°€à°żà°‚à°Șà°œà±‡à°Żà°Źà°Ąà°€à°Ÿà°Żà°ż.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ఈ ఞంఊేశం ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà°żà°‚à°Šà°ż.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "à°Șà±à°°à°Šà°°à±à°¶à°żà°‚à°šà±‡à°‚à°Šà±à°•à± à°…à°Ÿà°Ÿà°šà±â€Œà°źà±†à°‚à°Ÿà± à°šà°Ÿà°Čà°Ÿ à°Șà±†à°Šà±à°Šà°Šà°żà°—à°Ÿ à°‰à°‚à°Šà°ż.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "à°Șà±à°°à°Šà°°à±à°¶à°żà°‚à°šà±‡à°‚à°Šà±à°•à± à°•à±Šà°šà±à°šà°ż à°…à°Ÿà°Ÿà°šà±â€Œà°źà±†à°‚à°Ÿà±â€Œà°Čు à°šà°Ÿà°Čà°Ÿ à°Șà±†à°Šà±à°Šà°”à°żà°—à°Ÿ à°‰à°šà±à°šà°Ÿà°Żà°ż.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "à°”à°żà°°à°Ÿà°łà°‚ à°”à°żà°”à°°à°Ÿà°Čచు à°Șొంఊà°Čేకà°Șà±‹à°Żà°żà°‚à°Šà°ż", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal à°Źà±€à°Ÿà°Ÿ à°źà°Ÿà°€à±à°°à°źà±‡", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Signal à°Źà±€à°Ÿà°Ÿ à°Żà±‚à°œà°°à±à°Čకు à°źà°Ÿà°€à±à°°à°źà±‡ ఞంఊేశటà°Čచు à°žà°”à°°à°żà°‚à°šà°Ąà°‚ à°…à°‚à°Šà±à°Źà°Ÿà°Ÿà±à°Čో à°‰à°‚à°Šà°ż. à°’à°•à°”à±‡à°ł à°źà±€à°°à± ఒక à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°žà°”à°°à°żà°žà±à°€à±‡, Signal à°Źà±€à°Ÿà°Ÿ à°Żà±Šà°•à±à°• ఀటజట ఔెర్షచ్‌à°Șై ఉచ్చ à°”à±à°Żà°•à±à°€à±à°Čకు à°źà°Ÿà°€à±à°°à°źà±‡ à°‡à°Šà°ż à°•à°šà°Șà°Ąà±à°€à±à°‚à°Šà°ż.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°žà°”à°°à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "à°’à°•à°”à±‡à°ł à°źà±€à°°à± ఒక à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°žà°”à°°à°żà°žà±à°€à±‡, Signal à°Żà±Šà°•à±à°• ఀటజట ఔెర్షచ్‌à°Čà°Čో ఉచ్చ à°”à±à°Żà°•à±à°€à±à°Čకు à°źà°Ÿà°€à±à°°à°źà±‡ à°‡à°Šà°ż à°•à°šà°żà°Șà°żà°žà±à°€à±à°‚à°Šà°ż. à°źà±€à°°à± à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°žà°”à°°à°żà°‚à°šà°żà°šà°Ÿà±à°Čు ఔటరు à°šà±‚à°Ąà°—à°Čరు.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "à°‡à°šà±â€Œà°•à°źà°żà°‚à°—à± à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్ ", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "à°…à°”à±à°Ÿà±â€Œà°—à±‹à°Żà°żà°‚à°—à± à°”à°Ÿà°Żà°żà°žà± à°•à°Ÿà°Č్", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "à°…à°”à±à°Ÿà±à°—à±‹à°Żà°żà°‚à°—à± à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} à°źà±€à°•à± à°•à°Ÿà°Č్ చేఞ్ఀుచ్చటరు", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "à°€à°żà°°à°żà°—à°ż కచెక్ట్ à°šà±‡à°žà±à°€à±‹à°‚à°Šà°ż...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} à°”à±à°Żà°•à±à°€à°ż} other {{count,number}à°”à±à°Żà°•à±à°€à±à°Čు}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "à°†à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "à°źà±à°—à°żà°‚à°Șు", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "à°”à°Šà°żà°Čà±‡à°Żà°‚à°Ąà°ż", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "à°źà±ˆà°•à± ఆఫ్‌à°Čో à°‰à°‚à°Šà°ż", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "à°źà±ˆà°•à± ఆచ్‌à°Čో à°‰à°‚à°Šà°ż", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "à°°à°żà°‚à°—à± ఆచ్‌à°Čో à°‰à°‚à°Šà°ż", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "à°°à°żà°‚à°—à± ఆఫ్‌à°Čో à°‰à°‚à°Šà°ż", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "à°…à°źà°°à°żà°•à°Čు", @@ -3468,13 +3668,25 @@ "messageformat": "à°Șà±‚à°°à±à°€à°ż ఞ్క్రీచ్ à°•à°Ÿà°Č్", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "అà°Č్à°Čà°żà°• à°Șà°Šà±à°§à°€à°ż à°”à±€à°•à±à°·à°Łà°•à± à°źà°Ÿà°°à°‚à°Ąà°ż", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "à°”à±€à°•à±à°·à°Łà°šà± à°źà°Ÿà°°à±à°šà°‚à°Ąà°ż", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ఉà°Șà°šà±à°Żà°Ÿà°žà°•à±à°Ąà± à°”à±€à°•à±à°·à°Łà°•à± à°źà°Ÿà°°à°‚à°Ąà°ż", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "à°—à±à°°à°żà°Ąà± à°”à±€à°•à±à°·à°Ł", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "à°žà±ˆà°Ąà±â€Œà°Źà°Ÿà°°à± à°”à±€à°•à±à°·à°Ł", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ఞ్à°Șీకర్ à°”à±€à°•à±à°·à°Ł", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "à°”à±€à°•à±à°·à°Ł అà°Șà±â€Œà°Ąà±‡à°Ÿà± à°šà±‡à°Żà°Źà°Ąà°żà°‚à°Šà°ż", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "à°•à°Ÿà°Č్ à°šà°ż à°”à°Šà°żà°Čà°ż", @@ -3576,6 +3788,14 @@ "messageformat": "ఞరే", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "à°žà°‚à°Šà±‡à°¶à°Ÿà°šà±à°šà°ż à°žà°”à°°à°żà°‚à°šà°Ąà°‚ à°žà°Ÿà°§à±à°Żà°Șà°Ąà°Šà±", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ఈ à°žà°‚à°Šà±‡à°¶à°Ÿà°šà°żà°•à°ż {max,number} à°žà°”à°°à°Łà°Čుు à°źà°Ÿà°€à±à°°à°źà±‡ à°”à°°à±à°€à°żà°‚à°Șà°šà±‡à°Żà°Źà°Ąà°”à°šà±à°šà±.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "à°•à±à°·à°źà°żà°‚à°šà°‚à°Ąà°ż, ఆ sgnl: // à°Čà°żà°‚à°•à± అర్ధఔంఀం à°•à°Ÿà°Čేఊు!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "à°źà±€ à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°€à±‹ ఏఊో à°€à°Ș్à°Șు à°œà°°à°żà°—à°żà°‚à°Šà°ż, à°‡à°Šà°ż à°źà±€ ఖటఀటకు ఇక à°à°źà°Ÿà°€à±à°°à°‚ à°•à±‡à°Ÿà°Ÿà°Żà°żà°‚à°šà°Źà°Ąà°Čేఊు.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°šà± ఀొà°Čà°—à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "à°”à°żà°šà°żà°Żà±‹à°—à°Šà°Ÿà°°à± à°Șà±‡à°°à±à°šà°ż à°žà±ƒà°·à±à°Ÿà°żà°‚à°šà°‚à°Ąà°ż", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR à°•à±‹à°Ąà± à°Čేఊట à°Čà°żà°‚à°•à±", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà± రీఞెట్ à°šà±‡à°Żà°Źà°Ąà°Ÿà°Čà°ż", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà± à°Čà°żà°‚à°•à± రీఞెట్ à°šà±‡à°Żà°Źà°Ąà°Ÿà°Čà°ż", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "à°źà±€ à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°šà± à°Șà°‚à°šà±à°•à±‹à°‚à°Ąà°ż", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°šà± ఀొà°Čà°—à°żà°‚à°šà°‚à°Ąà°ż", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "à°‡à°Šà°ż à°źà±€ à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°šà± ఀొà°Čà°—à°żà°žà±à°€à±à°‚à°Šà°ż, ఇఀర à°Żà±‚à°œà°°à±â€Œà°Čు à°Šà°Ÿà°šà°żà°•à°ż క్à°Čà±†à°Żà°żà°‚ à°šà±‡à°Żà°Ąà°Ÿà°šà°żà°•à°ż à°…à°šà±à°źà°€à°żà°žà±à°€à±à°‚à°Šà°ż. à°źà±€à°°à± à°–à°šà±à°šà°żà°€à°‚à°—à°Ÿ అచుకుంటుచ్చటరట?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "à°‡à°Šà°ż à°źà±€ à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°šà± ఀొà°Čà°—à°żà°žà±à°€à±à°‚à°Šà°ż à°źà°°à°żà°Żà± à°źà±€ QR à°•à±‹à°Ąà± à°źà°°à°żà°Żà± à°Čà°żà°‚à°•à±â€Œà°šà± à°šà°żà°Čà°żà°Șà°żà°”à±‡à°žà±à°€à±à°‚à°Šà°ż. క్à°Čà±†à°Żà°żà°źà± à°šà±‡à°Żà°Ąà°Ÿà°šà°żà°•à°ż “{username}” ఇఀరుà°Čకు à°…à°‚à°Šà±à°Źà°Ÿà°Ÿà±à°Čో à°‰à°‚à°Ÿà±à°‚à°Šà°ż. à°źà±€à°°à± à°–à°šà±à°šà°żà°€à°‚à°—à°Ÿ à°šà±‡à°Żà°Ÿà°Čà°šà°ż అచుకుంటుచ్చటరట?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "à°źà±€à°°à± ఇక à°à°źà°Ÿà°€à±à°°à°‚ à°•à°„à°Čచు à°Șంచుకోà°Čేరు à°Čేఊట à°”à±€à°•à±à°·à°żà°‚à°šà°Čేరు. à°źà±€à°°à± ఇటీఔà°Č à°Șంచుకుచ్చ à°•à°„ అà°Șà±â€Œà°Ąà±‡à°Ÿà±à°žà± à°•à±‚à°Ąà°Ÿ ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà°€à°Ÿà°Żà°ż.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "à°­à°Ÿà°·", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "à°­à°Ÿà°·", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "à°žà°żà°žà±à°Ÿà°źà± à°­à°Ÿà°·", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "à°­à°Ÿà°·à°Čచు à°”à±†à°€à°•à°‚à°Ąà°ż", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "“{searchTerm}” కోఞం ఏ à°«à°Čà°żà°€à°Ÿà°Čు à°Čేఔు", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ఞెట్", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "à°”à°°à±à°€à°żà°‚à°Șà°œà±‡à°Żà°Ąà°Ÿà°šà°żà°•à°ż Signal చు రీఞ్టటర్ట్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "భటషచు à°źà°Ÿà°°à±à°šà°Ąà°Ÿà°šà°żà°•à°ż, à°Żà°Ÿà°Ș్ రీఞ్టటర్ట్ కటఔటà°Čà°ż.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "రీఞ్టటర్ట్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ఔెర్షచ్ {version}కు అà°Șà±â€Œà°Ąà±‡à°Ÿà± à°Čà°­à±à°Żà°źà°”à±à°€à±‹à°‚à°Šà°ż", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "à°źà±€ à°žà±†à°Ÿà±à°Ÿà°żà°‚à°—à±â€Œà°Čచు ఞేఔ్ చేఞేటà°Ș్à°Șà±à°Ąà± ఒక ఊోషం ఏర్à°Șà°Ąà°żà°‚à°Šà°ż, à°Šà°Żà°šà±‡à°žà°ż à°źà°łà±à°Čీ à°Șà±à°°à°Żà°€à±à°šà°żà°‚à°šà°‚à°Ąà°ż.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ఞంఊేశం", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "à°źà°°à°żà°šà±à°šà°ż ఞ్టైà°Č్ఞ్", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "à°Șà±à°šà°°à±à°Šà±à°§à°°à°żà°‚à°šà±", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "à°Șà±‚à°°à±à°€à°ż", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà± à°Čà°żà°‚à°•à± రంగు, {total,number} à°Čో {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "à°’à°•à°”à±‡à°ł à°źà±€à°°à± à°źà±€ QR à°•à±‹à°Ąà±â€Œà°šà± రీఞెట్ చేఞ్ఀే, à°źà±€ à°Ș్రఞ్ఀుఀ QR à°•à±‹à°Ąà± à°źà°°à°żà°Żà± à°Čà°żà°‚à°•à± ఇకà°Șై à°Șà°šà°ż à°šà±‡à°Żà°”à±.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "à°Čà°żà°‚à°•à±â€Œà°šà± రీఞెట్ à°šà±‡à°žà±à°€à±‹à°‚à°Šà°ż...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR à°•à±‹à°Ąà± à°źà°°à°żà°Żà± à°Čà°żà°‚à°•à± ఞెట్ à°šà±‡à°Żà°Źà°Ąà°Čేఊు. à°źà±€ చెట్‌ఔర్క్ కచెక్షచ్‌చు à°€à°šà°żà°–à±€ à°šà±‡à°Żà°‚à°Ąà°ż à°źà°°à°żà°Żà± à°źà°łà±à°łà±€ à°Șà±à°°à°Żà°€à±à°šà°żà°‚à°šà°‚à°Ąà°ż.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "à°źà±€ Signal à°Żà±‚à°œà°°à±â€Œà°šà±‡à°źà±â€Œà°šà± ఞెటà°Ș్ à°šà±‡à°Żà°‚à°Ąà°ż", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "à°źà°°à°Č à°Șంà°Șు", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "à°źà°°à°żà°šà±à°šà°ż à°šà°°à±à°Żà°Čు", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "à°•à°Ÿà°Č్ఞ్", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "కొఀ్ఀ à°•à°Ÿà°Č్", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "కొఀ్ఀ à°•à°Ÿà°Č్", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "à°źà°°à°żà°šà±à°šà°ż à°šà°°à±à°Żà°Čు", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "à°•à°Ÿà°Č్ à°šà°°à°żà°€à±à°°à°šà± ఀొà°Čà°—à°żà°‚à°šà°‚à°Ąà°ż", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "à°•à°Ÿà°Č్ à°šà°°à°żà°€à±à°°à°šà± ఀొà°Čà°—à°żà°‚à°šà±‡à°Šà°Ÿ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "à°‡à°Šà°ż à°•à°Ÿà°Č్ à°šà°°à°żà°€à±à°°à°šà± శటశ్ఔఀంగట ఀొà°Čà°—à°żà°žà±à°€à±à°‚à°Šà°ż", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ఞ్à°Șà°·à±à°Ÿà°źà±ˆà°š", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "à°•à°Ÿà°Č్ à°šà°°à°żà°€à±à°° ఀొà°Čà°—à°żà°‚à°šà°Źà°Ąà°żà°‚à°Šà°ż", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ఒక à°•à°Ÿà°Č్‌చు à°”à±€à°•à±à°·à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż à°Čేఊట à°Șà±à°°à°Ÿà°°à°‚à°­à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż క్à°Čà°żà°•à± à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "à°”à±†à°€à°•à°‚à°Ąà°ż", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "à°źà°żà°žà± à°…à°Żà°żà°š à°”à°Ÿà°Ÿà°ż ఆధటరంగట à°«à°żà°Č్టర్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "టోగుà°Č్ à°šà±‡à°Żà°‚à°Ąà°ż", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ఇటీఔà°Čà°ż à°•à°Ÿà°Č్ఞ్ à°Čేఔు ఞ్చేà°čà°żà°€à±à°Ąà°żà°•à°ż à°•à°Ÿà°Č్ à°šà±‡à°Żà°Ąà°‚ ఊ్ఔటరట à°Șà±à°°à°Ÿà°°à°‚à°­à°żà°‚à°šà°‚à°Ąà°ż.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "“{query}” కోఞం à°«à°Čà°żà°€à°Ÿà°Čు à°Čేఔు", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "à°‡à°šà±â€Œà°•à°źà°żà°‚à°—à±", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "అఔుట్ à°—à±‹à°Żà°żà°‚à°—à±", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "à°źà°żà°žà±à°Ąà±", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "à°žà°źà±‚à°č à°•à°Ÿà°Č్", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ఇటీఔà°Čà°ż à°žà°‚à°­à°Ÿà°·à°Łà°Čు ఏఔీ à°Čేఔు.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "“{query}” కోఞం à°«à°Čà°żà°€à°Ÿà°Čు à°Čేఔు", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {à°…à°”à±à°Ÿà±â€Œà°—à±‹à°Żà°żà°‚à°—à± à°”à°Ÿà°Żà°żà°žà± à°•à°Ÿà°Č్} other {à°‡à°šà±â€Œà°•à°źà°żà°‚à°—à± à°”à°Ÿà°Żà°żà°žà± à°•à°Ÿà°Č్}}} Video {{direction, select, Outgoing {à°…à°”à±à°Ÿà±à°—à±‹à°Żà°żà°‚à°—à± à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్} other {కొఀ్ఀగట à°”à°šà±à°šà°żà°š à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్}}} Group {{direction, select, Outgoing {à°…à°”à±à°Ÿà±â€Œà°—à±‹à°Żà°żà°‚à°—à± గ్రూà°Ș్ à°•à°Ÿà°Č్} other {à°‡à°šà±â€Œà°•à°źà°żà°‚à°—à± గ్రూà°Ș్ à°•à°Ÿà°Č్}}} other {{direction, select, Outgoing {à°…à°”à±à°Ÿà±à°—à±‹à°Żà°żà°‚à°—à± à°•à°Ÿà°Č్} other {క్రొఀ్ఀగట à°”à°šà±à°šà°żà°š à°•à°Ÿà°Č్}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {à°źà°żà°žà±à°Ąà± à°”à°Ÿà°Żà°żà°žà± à°•à°Ÿà°Č్} Video {à°€à°Ș్à°Șà°żà°š à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్} Group {à°źà°żà°žà± à°…à°Żà°żà°š గ్రూà°Ș్ à°•à°Ÿà°Č్} other {à°€à°Ș్à°Șà°żà°š à°•à°Ÿà°Č్}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {à°žà°źà°Ÿà°§à°Ÿà°šà°‚ à°‡à°”à±à°”à°šà°ż à°”à°Ÿà°Żà°żà°žà± à°•à°Ÿà°Č్} Video {à°žà°źà°Ÿà°§à°Ÿà°šà°‚ à°Čà±‡à°šà°ż à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్} Group {à°žà°źà°Ÿà°§à°Ÿà°šà°‚ à°‡à°”à±à°”à°Źà°Ąà°šà°ż గ్రూà°Ș్ à°•à°Ÿà°Č్} other {à°žà°źà°Ÿà°§à°Ÿà°šà°‚ à°‡à°”à±à°”à°Źà°Ąà°šà°ż à°•à°Ÿà°Č్}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {ఞ్ఔర à°•à°Ÿà°Č్ à°€à°żà°°à°žà±à°•à°°à°żà°‚à°šà°Źà°Ąà°żà°‚à°Šà°ż} Video {à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్ à°€à°żà°°à°žà±à°•à°°à°żà°‚à°šà°Źà°Ąà°żà°‚à°Šà°ż} Group {గ్రూà°Ș్ à°•à°Ÿà°Č్ à°€à°żà°°à°žà±à°•à°°à°żà°‚à°šà°Źà°Ąà°żà°‚à°Šà°ż} other {à°•à°Ÿà°Č్ à°€à°żà°°à°žà±à°•à°°à°żà°‚à°šà°Źà°Ąà°żà°‚à°Šà°ż}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ఇఀర à°”à±à°Żà°•à±à°€à°ż టైà°Ș్ చేఞ్ఀుచ్చటరు.} other {{count,number} à°źà°‚à°Šà°ż ఇఀర à°”à±à°Żà°•à±à°€à±à°Čు టైà°Ș్ చేఞ్ఀుచ్చటరు.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "à°•à±Šà°€à±à°€à°Šà°ż à°à°źà°żà°Ÿà°ż", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "à°šà°żà°šà±à°š ట్ఔీక్‌à°Čు, à°Źà°—à± à°«à°żà°•à±à°žà±â€Œà°Čు, à°źà°°à°żà°Żà± à°Șà°šà°żà°€à±€à°°à± à°źà±†à°°à±à°—à±à°Šà°Čà°Čు. Signal ఉà°Șà°Żà±‹à°—à°żà°‚à°šà°żà°šà°‚à°Šà±à°•à± à°źà±€à°•à± à°§à°šà±à°Żà°”à°Ÿà°Šà°Ÿà°Čు!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ఈ అà°Șà±â€Œà°Ąà±‡à°Ÿà± ఞ్ఔర à°źà°°à°żà°Żà± à°”à±€à°Ąà°żà°Żà±‹ à°•à°Ÿà°Č్ఞ్ కోఞం à°•à±Šà°šà±à°šà°ż à°źà±†à°°à±à°—à±à°Šà°Čà°Čు à°źà°°à°żà°Żà± à°•à±Šà°šà±à°šà°ż à°šà°żà°šà±à°š à°Ąà°Ÿà°•à±à°Żà±à°źà±†à°‚à°Ÿà±‡à°·à°šà± అà°Șà±â€Œà°Ąà±‡à°Ÿà±â€Œà°Čచు కà°Čà°żà°—à°żà°‰à°‚à°Šà°ż (à°§à°šà±à°Żà°”à°Ÿà°Šà°Ÿà°Čు, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "à°źà±€ à°žà°żà°žà±à°Ÿà°źà± à°žà±†à°Ÿà±à°Ÿà°żà°‚à°—à±â€Œà°Čచు à°źà°Ÿà°°à±à°šà°•à±à°‚à°Ąà°Ÿà°šà±‡ Signal à°Čో à°źà±€à°°à± ఎంచుకుచ్చ భటషచు ఇà°Ș్à°Șà±à°Ąà± à°źà±€à°°à± à°źà°Ÿà°°à±à°šà°”à°šà±à°šà± (Signal à°žà±†à°Ÿà±à°Ÿà°żà°‚à°—à±â€Œà°Čు > రూà°Șం > à°­à°Ÿà°·)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "à°źà±‡à°źà± à°•à±Šà°šà±à°šà°ż గ్రూà°Ș్ à°šà±‹à°Ÿà°żà°«à°żà°•à±‡à°·à°šà± ఐకటచ్‌à°Čచు అà°Șà±â€Œà°Ąà±‡à°Ÿà± à°šà±‡à°¶à°Ÿà°źà±." + "icu:WhatsNew__v6.39--1": { + "messageformat": "à°•à°Ÿà°Č్ à°Čà°Ÿà°Źà±€à°Čో à°šà±‡à°°à°żà°š ఀర్ఔటఀ macOS à°Čో à°•à±Šà°šà±à°šà°żà°žà°Ÿà°°à±à°Čు à°œà°°à°żà°—à°żà°š à°•à±Šà°Šà±à°Šà°żà°Șà°Ÿà°Ÿà°ż ఆà°Čà°žà±à°Żà°Ÿà°šà±à°šà°ż à°źà±‡à°źà± à°Șà°°à°żà°·à±à°•à°°à°żà°‚à°šà°Ÿà°źà±." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ఎఔరైచట గ్రూà°Ș్ à°•à°Ÿà°Č్‌à°Čో à°šà±‡à°°à°żà°šà°Ș్à°Șà±à°Ąà± à°Čేఊట à°”à°Šà°żà°Čà°ż à°”à±†à°łà±à°łà°żà°šà°Ș్à°Șà±à°Ąà± à°”à±€à°Ąà°żà°Żà±‹ టైà°Č్ఞ్ కోఞం à°žà±à°„à°żà°€à±à°Żà°‚à°€à°° à°Żà°Ÿà°šà°żà°źà±‡à°·à°šà±â€Œà°šà± à°źà±‡à°źà± à°Șà°°à°żà°·à±à°•à°°à°żà°‚à°šà°Ÿà°źà±. ఞ్చేà°čà°żà°€à±à°Ąà°ż à°źà±à°–à°Ÿà°šà±à°šà°ż à°šà±‚à°žà°żà°šà°Ș్à°Șà±à°Ąà± à°”à±€à°•à±à°·à°Łà°Čà±‹à°•à°ż à°œà°Ÿà°°à±à°•à±‹à°‚à°Ąà°ż, à°‡à°Šà°ż ఒక à°žà°Ÿà°źà°Ÿà°œà°żà°• చేష్ట." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "చటట్ à°žà±†à°Ÿà±à°Ÿà°żà°‚à°—à±â€Œà°Čచు ఔేగంగట à°Żà°Ÿà°•à±à°žà±†à°žà± à°šà±‡à°Żà°Ąà°Ÿà°šà°żà°•à°ż à°Čేఊట ఆ చటట్ à°šà±à°‚à°Ąà°ż à°•à°šà°żà°Șà°żà°‚à°šà°šà°ż à°•à°„à°Čచు à°”à±€à°•à±à°·à°żà°‚à°šà°Ąà°Ÿà°šà°żà°•à°ż చటట్ à°čà±†à°Ąà°°à±â€Œà°Čà±‹à°šà°ż à°Ș్రొఫైà°Č్ ఫోటో à°Čేఊట గ్రూà°Ș్ అఔఀటర్‌à°Șై ఇà°Ș్à°Șà±à°Ąà± à°źà±€à°°à± క్à°Čà°żà°•à± à°šà±‡à°Żà°”à°šà±à°šà±. à°§à°šà±à°Żà°”à°Ÿà°Šà°Ÿà°Čు, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/th/messages.json b/_locales/th/messages.json index a11f9cb3c1..cf773278c6 100644 --- a/_locales/th/messages.json +++ b/_locales/th/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "àžàžČàž™àž‚àč‰àž­àžĄàžčàž„àžœàžŽàž”àžžàž„àžČàž”", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "àč€àžàžŽàž”àž‚àč‰àž­àžœàžŽàž”àžžàž„àžČàž”àž”àč‰àžČàž™àžàžČàž™àž‚àč‰àž­àžĄàžčàž„ àž„àžžàž“àžȘàžČàžĄàžČàžŁàž–àž„àž±àž”àž„àž­àžàž‚àč‰àž­àžĄàžčàž„àž„àž§àžČàžĄàžœàžŽàž”àžžàž„àžČàž”àž™àž”àč‰àčàž„àč‰àž§àž•àžŽàž”àž•àčˆàž­àžàčˆàžČàžąàžȘàž™àž±àžšàžȘàž™àžžàž™àž‚àž­àž‡ Signal àčƒàž«àč‰àžŠàčˆàž§àžąàčàžàč‰àč„àž‚àž›àž±àžàž«àžČàž”àž±àž‡àžàž„àčˆàžČàž§ àčƒàž™àžàžŁàž“àž”àž—àž”àčˆàž„àžžàž“àž•àč‰àž­àž‡àžàžČàžŁàčƒàžŠàč‰ Signal àž—àž±àž™àž—àž” àž„àžžàž“àžȘàžČàžĄàžČàžŁàž–àž„àžšàž‚àč‰àž­àžĄàžčàž„àčàž„àž°àžŁàž”àžȘàž•àžČàžŁàčŒàž—àč„àž”àč‰\n\nàž•àžŽàž”àž•àčˆàž­àžàčˆàžČàžąàžȘàž™àž±àžšàžȘàž™àžžàž™àč‚àž”àžąàč„àž›àž—àž”àčˆ: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "àž„àžšàž‚àč‰àž­àžĄàžčàž„àž—àž±àč‰àž‡àž«àžĄàž”àčàž„àž°àžŁàž”àžȘàž•àžČàžŁàčŒàž—", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "àž„àžšàž‚àč‰àž­àžĄàžčàž„àčàž„àž°àžŁàž”àžȘàž•àžČàžŁàčŒàž—", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "àž„àžšàž‚àč‰àž­àžĄàžčàž„àž—àž±àč‰àž‡àž«àžĄàž”àž­àžąàčˆàžČàž‡àž–àžČàž§àžŁàčƒàžŠàčˆàž«àžŁàž·àž­àč„àžĄàčˆ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "àž›àžŁàž°àž§àž±àž•àžŽàžàžČàžŁàžȘàčˆàž‡àž‚àč‰àž­àž„àž§àžČàžĄàčàž„àž°àžȘàž·àčˆàž­àž—àž±àč‰àž‡àž«àžĄàž”àž‚àž­àž‡àž„àžžàž“àžˆàž°àž–àžčàžàž„àžšàž­àž­àžàžˆàžČàžàž­àžžàž›àžàžŁàž“àčŒàž™àž”àč‰àž­àžąàčˆàžČàž‡àž–àžČàž§àžŁ àž„àžžàž“àžˆàž°àžȘàžČàžĄàžČàžŁàž–àčƒàžŠàč‰ Signal àžšàž™àž­àžžàž›àžàžŁàž“àčŒàž™àž”àč‰àč„àž”àč‰àž«àž„àž±àž‡àžˆàžČàžàč€àžŠàž·àčˆàž­àžĄàč‚àžąàž‡àž­àžžàž›àžàžŁàž“àčŒàž­àž”àžàž„àžŁàž±àč‰àž‡ àč‚àž”àžąàžàžČàžŁàž”àžłàč€àž™àžŽàž™àžàžČàžŁàž™àž”àč‰àžˆàž°àč„àžĄàčˆàž„àžšàž‚àč‰àž­àžĄàžčàž„àž­àž­àžàžˆàžČàžàč‚àž—àžŁàžšàž±àžžàž—àčŒàž‚àž­àž‡àž„àžžàž“", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "àč€àž§àž­àžŁàčŒàžŠàž±àž™àžàžČàž™àž‚àč‰àž­àžĄàžčàž„àž‚àž­àž‡àž„àžžàž“àč„àžĄàčˆàž•àžŁàž‡àžàž±àžš Signal àč€àž§àž­àžŁàčŒàžŠàž±àž™àž™àž”àč‰ àž•àžŁàž§àžˆàžȘàž­àžšàčƒàž«àč‰àčàž™àčˆàčƒàžˆàž§àčˆàžČ Signal àž—àž”àčˆàž„àžžàž“àč€àž›àžŽàž”àž­àžąàžčàčˆàžšàž™àž„àž­àžĄàžžàžŽàž§àč€àž•àž­àžŁàčŒàč€àž›àč‡àž™àč€àž§àž­àžŁàčŒàžŠàž±àž™àž„àčˆàžČàžȘàžžàž”", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "àč&àžŸàč‰àžĄ", @@ -300,6 +316,70 @@ "messageformat": "àčàžŠàž—", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "àč€àžàžŽàž”àž‚àč‰àž­àžœàžŽàž”àžžàž„àžČàž”àč€àžàž”àčˆàžąàž§àžàž±àžšàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰ àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčƒàžŠàč‰àžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž™àž”àč‰àžàž±àžšàžšàž±àžàžŠàž”àž‚àž­àž‡àž„àžžàž“àč„àž”àč‰àž­àž”àžàž•àčˆàž­àč„àž› àč‚àž›àžŁàž”àž„àž­àž‡àčƒàž«àžĄàčˆàž”àč‰àž§àžąàžàžČàžŁàčƒàžȘàčˆàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž­àž”àžàž„àžŁàž±àč‰àž‡àž«àžŁàž·àž­àž•àž±àč‰àž‡àžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àčƒàž«àžĄàčˆ", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "àčàžàč‰àč„àž‚àž•àž­àž™àž™àž”àč‰", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "àč€àžàžŽàž”àž‚àč‰àž­àžœàžŽàž”àžžàž„àžČàž”àč€àžàž”àčˆàžąàž§àžàž±àžšàž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž”àčàž„àž°àž„àžŽàž‡àžàčŒàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž‚àž­àž‡àž„àžžàž“ àžˆàž¶àž‡àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčƒàžŠàč‰àž„àžŽàž‡àžàčŒàž™àž”àč‰àč„àž”àč‰àž­àž”àžàž•àčˆàž­àč„àž› àč‚àž›àžŁàž”àžȘàžŁàč‰àžČàž‡àž„àžŽàž‡àžàčŒàčƒàž«àžĄàčˆàč€àžžàž·àčˆàž­àčƒàžŠàč‰àžȘàžłàž«àžŁàž±àžšàčàžŠàžŁàčŒàžàž±àžšàžœàžčàč‰àž•àžŽàž”àž•àčˆàž­", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "àčàžàč‰àč„àž‚àž•àž­àž™àž™àž”àč‰", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "àčàžȘàž”àž‡àčàž—àč‡àžš", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "àž‹àčˆàž­àž™àčàž—àč‡àžš", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "àč€àžàžŽàž”àž‚àč‰àž­àžœàžŽàž”àžžàž„àžČàž”", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "àžąàž±àž‡àč„àžĄàčˆàč„àž”àč‰àž­àčˆàžČàž™ {count,number} àžŁàžČàžąàžàžČàžŁ", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "àž–àžčàžàž—àžłàč€àž„àžŁàž·àčˆàž­àž‡àž«àžĄàžČàžąàž§àčˆàžČàžąàž±àž‡àč„àžĄàčˆàč„àž”àč‰àž­àčˆàžČàž™", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "àčàžŠàž—", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "àžàžČàžŁàč‚àž—àžŁ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "àžȘàž•àž­àžŁàž”àčˆ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "àžàžČàžŁàž•àž±àč‰àž‡àž„àčˆàžČ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "àž›àžŁàž±àžšàž›àžŁàžžàž‡ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "àč‚àž›àžŁàč„àžŸàž„àčŒ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "àžàž„àž±àžš", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "àčàžŠàž—àč€àž«àž„àčˆàžČàž™àž”àč‰àžˆàž°àž–àžčàžàč€àžàč‡àžšàčƒàž™àž—àž”àčˆàč€àžàč‡àžšàž–àžČàž§àžŁàčàž„àž°àžˆàž°àčàžȘàž”àž‡àčƒàž™àžàž„àčˆàž­àž‡àž‚àžČàč€àž‚àč‰àžČàžàč‡àž•àčˆàž­àč€àžĄàž·àčˆàž­àč„àž”àč‰àžŁàž±àžšàž‚àč‰àž­àž„àž§àžČàžĄàčƒàž«àžĄàčˆ", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "àžąàž·àž™àžąàž±àž™àž—àž”àčˆàžˆàž°àč‚àž—àžŁ", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "àžąàž·àž™àžąàž±àž™àž—àž”àčˆàžˆàž°àč€àž‚àč‰àžČàžŁàčˆàž§àžĄ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "àž”àžłàč€àž™àžŽàž™àžàžČàžŁàč‚àž—àžŁàž•àčˆàž­", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "àžàžłàž„àž±àž‡àž­àž±àž›àč€àž”àž•àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžą", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "àč€àžŁàž”àžąàž™àžŁàžčàč‰àč€àžžàžŽàčˆàžĄàč€àž•àžŽàžĄ", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàžàčˆàž­àž™àž«àž™àč‰àžČ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàž–àž±àž”àč„àž›", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàč€àž§àž­àžŁàčŒàžŠàž±àž™àž—àž”àčˆ {index,number} àžˆàžČàž {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "àž—àžłàč€àž„àžŁàž·àčˆàž­àž‡àž«àžĄàžČàžąàž§àčˆàžČàžąàž·àž™àžąàž±àž™àčàž„àč‰àž§", @@ -663,33 +747,41 @@ "messageformat": "àž„àč‰àžČàž‡àžàžČàžŁàžąàž·àž™àžąàž±àž™", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "àč€àžžàž·àčˆàž­àžąàž·àž™àžąàž±àž™àž§àčˆàžČàžàžČàžŁàž•àžŽàž”àž•àčˆàž­àžȘàž·àčˆàž­àžȘàžČàžŁàžàž±àžš {name} àž–àžčàžàč€àž‚àč‰àžČàžŁàž«àž±àžȘàž•àž±àč‰àž‡àčàž•àčˆàž•àč‰àž™àž—àžČàž‡àž–àž¶àž‡àž›àž„àžČàžąàž—àžČàž‡ àčƒàž«àč‰àč€àž›àžŁàž”àžąàžšàč€àž—àž”àžąàžšàž«àžĄàžČàžąàč€àž„àž‚àž”àč‰àžČàž™àžšàž™àž™àž”àč‰àžàž±àžšàž«àžĄàžČàžąàč€àž„àž‚àžšàž™àž­àžžàž›àžàžŁàž“àčŒàž‚àž­àž‡àž„àž™àž„àž™àž™àž±àč‰àž™àž§àčˆàžČàž•àžŁàž‡àžàž±àž™àž«àžŁàž·àž­àč„àžĄàčˆ àž«àžŁàž·àž­àž­àžČàžˆàčƒàž«àč‰àžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àčƒàžŠàč‰àž­àžžàž›àžàžŁàž“àčŒàčƒàž™àžàžČàžŁàžȘàčàžàž™àžŁàž«àž±àžȘàž‚àž­àž‡àž„àžžàž“àžàč‡àč„àž”àč‰", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "àč€àžŁàž”àžąàž™àžŁàžčàč‰àč€àžžàžŽàčˆàžĄàč€àž•àžŽàžĄ", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "àč€àžžàž·àčˆàž­àžąàž·àž™àžąàž±àž™àž§àčˆàžČàžàžČàžŁàž•àžŽàž”àž•àčˆàž­àžȘàž·àčˆàž­àžȘàžČàžŁàžàž±àžš {name} àž–àžčàžàč€àž‚àč‰àžČàžŁàž«àž±àžȘàž•àž±àč‰àž‡àčàž•àčˆàž•àč‰àž™àž—àžČàž‡àž–àž¶àž‡àž›àž„àžČàžąàž—àžČàž‡ àčƒàž«àč‰àč€àž›àžŁàž”àžąàžšàč€àž—àž”àžąàžšàž«àžĄàžČàžąàč€àž„àž‚àčƒàž™àčàž–àžšàžȘàž”àž”àč‰àžČàž™àžšàž™àž™àž”àč‰àžàž±àžšàž«àžĄàžČàžąàč€àž„àž‚àžšàž™àž­àžžàž›àžàžŁàž“àčŒàž‚àž­àž‡àž„àž™àž„àž™àž™àž±àč‰àž™àž§àčˆàžČàž•àžŁàž‡àžàž±àž™àž«àžŁàž·àž­àč„àžĄàčˆ àž«àžČàžàž‚àč‰àž­àžĄàžčàž„àč„àžĄàčˆàž•àžŁàž‡àžàž±àž™ àčƒàž«àč‰àž„àž­àž‡àžˆàž±àžšàž„àžčàčˆàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàčƒàž«àžĄàčˆ àžàžČàžŁàž•àžŁàž§àžˆàžȘàž­àžšàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàčƒàž«àč‰àž•àžŁàž‡àžàž±àž™àč„àž”àč‰àž«àž™àž¶àčˆàž‡àž„àžčàčˆàž™àž±àč‰àž™àč€àžžàž”àžąàž‡àžžàž­àčàž„àč‰àž§", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "àč€àžžàž·àčˆàž­àžąàž·àž™àžąàž±àž™àž§àčˆàžČàžàžČàžŁàž•àžŽàž”àž•àčˆàž­àžȘàž·àčˆàž­àžȘàžČàžŁàžàž±àžš {name} àž–àžčàžàč€àž‚àč‰àžČàžŁàž«àž±àžȘàž•àž±àč‰àž‡àčàž•àčˆàž•àč‰àž™àž—àžČàž‡àž–àž¶àž‡àž›àž„àžČàžąàž—àžČàž‡ àčƒàž«àč‰àč€àž›àžŁàž”àžąàžšàč€àž—àž”àžąàžšàž«àžĄàžČàžąàč€àž„àž‚àž”àč‰àžČàž™àžšàž™àž™àž”àč‰àžàž±àžšàž«àžĄàžČàžąàč€àž„àž‚àžšàž™àž­àžžàž›àžàžŁàž“àčŒàž‚àž­àž‡àž„àž™àž„àž™àž™àž±àč‰àž™àž§àčˆàžČàž•àžŁàž‡àžàž±àž™àž«àžŁàž·àž­àč„àžĄàčˆ àž«àžŁàž·àž­àž­àžČàžˆàčƒàž«àč‰àžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àčƒàžŠàč‰àž­àžžàž›àžàžŁàž“àčŒàčƒàž™àžàžČàžŁàžȘàčàžàž™àžŁàž«àž±àžȘàž‚àž­àž‡àž„àžžàž“àžàč‡àč„àž”àč‰", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "àžàžČàžŁàč€àž›àž„àž”àčˆàžąàž™àčàž›àž„àž‡àč€àžàž”àčˆàžąàž§àžàž±àžšàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžą", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "àžàžłàž„àž±àž‡àž­àž±àž›àč€àž”àž•àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàč€àžžàž·àčˆàž­àčƒàž«àč‰àžžàžŁàč‰àž­àžĄàžŁàž­àž‡àžŁàž±àžšàžàžČàžŁàčƒàžŠàč‰àž‡àžČàž™àžŸàž”àč€àžˆàž­àžŁàčŒàž”àč‰àžČàž™àž„àž§àžČàžĄàč€àž›àč‡àž™àžȘàčˆàž§àž™àž•àž±àž§àčƒàž«àžĄàčˆàč† àž‚àž­àž‡ Signal", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "àč€àžžàž·àčˆàž­àžąàž·àž™àžąàž±àž™àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžą àčƒàž«àč‰àč€àž›àžŁàž”àžąàžšàč€àž—àž”àžąàžšàž«àžĄàžČàžąàč€àž„àž‚àčƒàž™àčàž–àžšàžȘàž”àžàž±àžšàž«àžĄàžČàžąàč€àž„àž‚àžšàž™àž­àžžàž›àžàžŁàž“àčŒàž‚àž­àž‡àžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àž§àčˆàžČàž•àžŁàž‡àžàž±àž™àž«àžŁàž·àž­àč„àžĄàčˆ àž«àžČàžàž‚àč‰àž­àžĄàžčàž„àč„àžĄàčˆàž•àžŁàž‡àžàž±àž™ àčƒàž«àč‰àž„àž­àž‡àžˆàž±àžšàž„àžčàčˆàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàčƒàž«àžĄàčˆ àžàžČàžŁàž•àžŁàž§àžˆàžȘàž­àžšàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàčƒàž«àč‰àž•àžŁàž‡àžàž±àž™àč„àž”àč‰àž«àž™àž¶àčˆàž‡àž„àžčàčˆàž™àž±àč‰àž™àč€àžžàž”àžąàž‡àžžàž­àčàž„àč‰àž§", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "àž•àč‰àž­àž‡àžàžČàžŁàž„àž§àžČàžĄàžŠàčˆàž§àžąàč€àž«àž„àž·àž­àž«àžŁàž·àž­àč„àžĄàčˆ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "àč€àž‚àč‰àžČàčƒàžˆàčàž„àč‰àž§", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "àžŁàž°àžšàžšàžˆàž°àžȘàžŁàč‰àžČàž‡àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàžȘàžłàž«àžŁàž±àžšàžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àž«àž„àž±àž‡àžˆàžČàžàž—àž”àčˆàž„àžžàž“àžȘàčˆàž‡àž«àžŁàž·àž­àžŁàž±àžšàž‚àč‰àž­àž„àž§àžČàžĄàžˆàžČàžàž„àž™àž„àž™àž™àž”àč‰", @@ -1267,10 +1359,6 @@ "messageformat": "àž”àžčàžȘàž·àčˆàž­àž„àžŁàž±àč‰àž‡àž„àčˆàžČàžȘàžžàž”", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "àč€àžžàž·àčˆàž­àžąàž·àž™àžąàž±àž™àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàčƒàž™àžàžČàžŁàž•àžŽàž”àž•àčˆàž­àžȘàž·àčˆàž­àžȘàžČàžŁàžàž±àžš {name} àž§àčˆàžČàž–àžčàžàč€àž‚àč‰àžČàžŁàž«àž±àžȘàž•àž±àč‰àž‡àčàž•àčˆàž•àč‰àž™àž—àžČàž‡àž–àž¶àž‡àž›àž„àžČàžąàž—àžČàž‡ àčƒàž«àč‰àč€àž›àžŁàž”àžąàžšàč€àž—àž”àžąàžšàž«àžĄàžČàžąàč€àž„àž‚àž”àč‰àžČàž™àžšàž™àž™àž”àč‰àžàž±àžšàž«àžĄàžČàžąàč€àž„àž‚àžšàž™àž­àžžàž›àžàžŁàž“àčŒàž‚àž­àž‡àž„àž™àž„àž™àž™àž±àč‰àž™àž§àčˆàžČàž•àžŁàž‡àžàž±àž™àž«àžŁàž·àž­àč„àžĄàčˆ àž«àžŁàž·àž­àž­àžČàžˆàčƒàž«àč‰àžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àžȘàčàžàž™àž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž”àž”àč‰àžČàž™àžšàž™àž™àž”àč‰àžàč‡àč„àž”àč‰", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "àž„àžžàž“àžąàž±àž‡àč„àžĄàčˆàč„àž”àč‰àčàž„àžàč€àž›àž„àž”àčˆàžąàž™àž‚àč‰àž­àž„àž§àžČàžĄàčƒàž”àč† àžàž±àžšàžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àžŁàžČàžąàž™àž”àč‰ àž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžąàž‚àž­àž‡àž„àžžàž“àžàž±àžšàč€àž‚àžČàžˆàž°àžĄàž”àčƒàž«àč‰àž«àž„àž±àž‡àžȘàčˆàž‡àž‚àč‰àž­àž„àž§àžČàžĄàčàžŁàž" }, @@ -1334,17 +1422,17 @@ "messageformat": "àž‚àč‰àž­àžĄàžčàž„", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "àž„àžš", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "àž„àžšàž‚àč‰àž­àž„àž§àžČàžĄ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "àž„àžšàčàžŠàž—àčƒàžŠàčˆàž«àžŁàž·àž­àč„àžĄàčˆ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "àž„àžšàž‚àč‰àž­àž„àž§àžČàžĄàž«àžŁàž·àž­àč„àžĄàčˆ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "àžŁàž°àžšàžšàžˆàž°àž„àžšàčàžŠàž—àž™àž”àč‰àž­àž­àžàžˆàžČàžàž­àžžàž›àžàžŁàž“àčŒàč€àž„àžŁàž·àčˆàž­àž‡àž™àž”àč‰", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "àžŁàž°àžšàžšàžˆàž°àž„àžšàž‚àč‰àž­àž„àž§àžČàžĄàčƒàž™àčàžŠàž—àž­àž­àžàžˆàžČàžàž­àžžàž›àžàžŁàž“àčŒàč€àž„àžŁàž·àčˆàž­àž‡àž™àž”àč‰ àč‚àž”àžąàž„àžžàž“àžˆàž°àžąàž±àž‡àžȘàžČàžĄàžČàžŁàž–àž„àč‰àž™àž«àžČàčàžŠàž—àž™àž”àč‰àč„àž”àč‰àčàžĄàč‰àžˆàž°àž„àžšàž‚àč‰àž­àž„àž§àžČàžĄàč„àž›àčàž„àč‰àž§", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "àž­àž­àžàžˆàžČàžàžàž„àžžàčˆàžĄ", @@ -1438,6 +1526,14 @@ "messageformat": "àž›àžŁàž°àž§àž±àž•àžŽàžàžČàžŁàžȘàčˆàž‡àž‚àč‰àž­àž„àž§àžČàžĄàžȘàžłàž«àžŁàž±àžšàčàžŠàž—àž—àž±àč‰àž‡àžȘàž­àž‡àžŁàžČàžąàžàžČàžŁàž–àžčàžàžŁàž§àžĄàč„àž§àč‰àčƒàž™àž™àž”àč‰", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} àč€àž›àč‡àž™àž«àžĄàžČàžąàč€àž„àž‚àč‚àž—àžŁàžšàž±àžžàž—àčŒàž‚àž­àž‡ {conversationTitle} àž„àžžàž“àž—àž±àč‰àž‡àž„àžčàčˆàč€àž›àč‡àž™àžȘàžĄàžČàžŠàžŽàžàž‚àž­àž‡ {sharedGroup}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} àč€àž›àč‡àž™àž«àžĄàžČàžąàč€àž„àž‚àč‚àž—àžŁàžšàž±àžžàž—àčŒàž‚àž­àž‡ {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "àžŁàžčàž›àžąàčˆàž­àž‚àž­àž‡àž àžČàžžàčƒàž™àž‚àč‰àž­àž„àž§àžČàžĄàž—àž”àčˆàžąàžàžĄàžČ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "àč‚àž—àžŁàž­àž”àžàž„àžŁàž±àč‰àž‡", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "àč€àžŁàžŽàčˆàžĄàč‚àž—àžŁ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "àč€àž‚àč‰àžČàžŁàčˆàž§àžĄàžȘàžČàžą", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "àč„àžĄàč‚àž„àžŁàč‚àžŸàž™àž–àžčàžàž›àžŽàž”àč€àžȘàž”àžąàž‡àč€àž™àž·àčˆàž­àž‡àžˆàžČàžàžĄàž”àžœàžčàč‰àčƒàžŠàč‰àžȘàžČàžąàžˆàžłàž™àž§àž™àžĄàžČàž", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "àžàžČàžŁàčàžˆàč‰àž‡àč€àž•àž·àž­àž™àčƒàž™àžàžČàžŁàč‚àž—àžŁ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "àž«àč‰àž­àž‡àč€àž•àč‡àžĄ", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "àžàž„àč‰àž­àž‡", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "àč€àž‚àč‰àžČàžŁàčˆàž§àžĄ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "àč€àžŁàžŽàčˆàžĄ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "àž«àč‰àž­àž‡àč€àž•àč‡àžĄ", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "àčƒàžŠàč‰àžàž„àč‰àž­àž‡àč„àžĄàčˆàč„àž”àč‰", @@ -1621,10 +1725,6 @@ "messageformat": "àč€àž›àžŽàž”àžàž„àč‰àž­àž‡", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "àž›àžŽàž”àč€àžȘàž”àžąàž‡", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "àčƒàžŠàč‰àč„àžĄàč‚àž„àžŁàč‚àžŸàž™àč„àžĄàčˆàč„àž”àč‰", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "àč€àž›àžŽàž”àč€àžȘàž”àžąàž‡àč„àžĄàž„àčŒ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "àčàžšàčˆàž‡àž›àž±àž™", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "àžàžČàžŁàž™àžłàč€àžȘàž™àž­àž›àžŽàž”àčƒàžŠàč‰àž‡àžČàž™àž­àžąàžčàčˆ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "àž«àžąàžžàž”àžàžČàžŁàž™àžłàč€àžȘàž™àž­", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "àžȘàčˆàž‡àč€àžȘàž”àžąàž‡àč€àžŁàž”àžąàž", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "àžàž„àžžàčˆàžĄàčƒàž«àžàčˆàč€àžàžŽàž™àč„àž›àž—àž”àčˆàžˆàž°àžˆàž±àžšàžàž„àžžàčˆàžĄàžœàžčàč‰àč€àž‚àč‰àžČàžŁàčˆàž§àžĄ", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "àč€àž›àžŽàž”àčƒàžŠàč‰àž‡àžČàž™àžàžČàžŁàžȘàčˆàž‡àč€àžȘàž”àžąàž‡àč€àžŁàž”àžąàž", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "àž›àžŽàž”àžàžČàžŁàžȘàčˆàž‡àč€àžȘàž”àžąàž‡àč€àžŁàž”àžąàžàžȘàžČàžą", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "àč€àž›àžŽàž”àžàžČàžŁàžȘàčˆàž‡àč€àžȘàž”àžąàž‡àč€àžŁàž”àžąàžàžȘàžČàžą", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "àž•àž±àž§àč€àž„àž·àž­àžàč€àžžàžŽàčˆàžĄàč€àž•àžŽàžĄ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "àž„àžžàž“", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "àžàž„àč‰àž­àž‡àž‚àž­àž‡àž„àžžàž“àž›àžŽàž”àž­àžąàžčàčˆ", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "àž”àžčàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžą", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "àžȘàčˆàž‡àž‚àč‰àž­àž„àž§àžČàžĄ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "àž”àžčàž«àžĄàžČàžąàč€àž„àž‚àž„àž§àžČàžĄàž›àž„àž­àž”àž àž±àžą", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àž”àž¶àž‡àž«àžĄàžČàžąàč€àž„àž‚àč‚àž—àžŁàžšàž±àžžàž—àčŒàč„àž”àč‰ àž•àžŁàž§àžˆàžȘàž­àžšàžàžČàžŁàč€àžŠàž·àčˆàž­àžĄàž•àčˆàž­àž‚àž­àž‡àž„àžžàž“àčàž„àč‰àž§àž„àž­àž‡àž­àž”àžàž„àžŁàž±àč‰àž‡", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "àžȘàžČàžĄàžČàžŁàž–àčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄàž™àž”àč‰àč„àž”àč‰àž àžČàžąàčƒàž™ 3 àžŠàž±àčˆàž§àč‚àžĄàž‡àž™àž±àžšàžˆàžČàžàč€àž§àž„àžČàž—àž”àčˆàž„àžžàž“àžȘàčˆàž‡", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "àžȘàžČàžĄàžČàžŁàž–àčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄàž™àž”àč‰àč„àž”àč‰àž àžČàžąàčƒàž™ 24 àžŠàž±àčˆàž§àč‚àžĄàž‡àž™àž±àžšàžˆàžČàžàč€àž§àž„àžČàž—àž”àčˆàž„àžžàž“àžȘàčˆàž‡", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "àž‚àč‰àž­àž„àž§àžČàžĄàž™àž”àč‰àž–àžčàžàž„àžš", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčàžȘàž”àž‡àč„àžŸàž„àčŒàčàž™àžšàč„àž”àč‰àč€àž™àž·àčˆàž­àž‡àžˆàžČàžàž‚àž™àžČàž”àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž›", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčàžȘàž”àž‡àč„àžŸàž„àčŒàčàž™àžšàžšàžČàž‡àč„àžŸàž„àčŒàč„àž”àč‰àč€àž™àž·àčˆàž­àž‡àžˆàžČàžàž‚àž™àžČàž”àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž›", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àč€àžŁàž”àžąàžàž”àžčàžŁàžČàžąàž„àž°àč€àž­àž”àžąàž”àžàžČàžŁàžšàžŁàžŽàžˆàžČàž„àč„àž”àč‰", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "àžȘàžłàž«àžŁàž±àžš Signal àžŁàžžàčˆàž™àč€àžšàž•àč‰àžČàč€àž—àčˆàžČàž™àž±àč‰àž™", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "àžŸàž”àč€àžˆàž­àžŁàčŒàčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄàžĄàž”àčƒàž«àč‰àžšàžŁàžŽàžàžČàžŁàč€àž‰àžžàžČàž°àčƒàž™àžœàžčàč‰àčƒàžŠàč‰ Signal àžŁàžžàčˆàž™àč€àžšàž•àč‰àžČàč€àž—àčˆàžČàž™àž±àč‰àž™ àčàž„àž°àžœàžčàč‰àčƒàžŠàč‰ Signal àžŁàžžàčˆàž™àč€àžšàž•àč‰àžČàč€àž§àž­àžŁàčŒàžŠàž±àž™àž„àčˆàžČàžȘàžžàž”àč€àž—àčˆàžČàž™àž±àč‰àž™àž—àž”àčˆàžˆàž°àč€àž«àč‡àž™àž‚àč‰àž­àž„àž§àžČàžĄàž—àž”àčˆàčàžàč‰àč„àž‚àčàž„àč‰àž§", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "àčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "àžœàžčàč‰àž•àžŽàž”àž•àčˆàž­àž•àč‰àž­àž‡àčƒàžŠàč‰ Signal àč€àž§àž­àžŁàčŒàžŠàž±àž™àž„àčˆàžČàžȘàžžàž”àžˆàž¶àž‡àžˆàž°àžȘàžČàžĄàžČàžŁàž–àč€àž«àč‡àž™àž‚àč‰àž­àž„àž§àžČàžĄàž—àž”àčˆàž„àžžàž“àčàžàč‰àč„àž‚àčàž„àč‰àž§ àčàž„àž°àž„àž™àž„àž™àž™àž±àč‰àž™àžˆàž°àč€àž«àč‡àž™àž§àčˆàžČàž„àžžàž“àčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄ", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "àž§àžŽàž”àž”àč‚àž­àž„àž­àž„àč€àžŁàž”àžąàžàč€àž‚àč‰àžČ
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "àžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡àž‚àžČàž­àž­àž", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "àžȘàžČàžąàž§àžŽàž”àž”àč‚àž­àč‚àž—àžŁàž­àž­àž", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} àžàžłàž„àž±àž‡àč‚àž—àžŁàž«àžČàž„àžžàž“", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "àžàžłàž„àž±àž‡àč€àžŠàž·àčˆàž­àžĄàž•àčˆàž­àčƒàž«àžĄàčˆâ€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} àž„àž™}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "àč‚àž—àžŁàč€àžȘàž”àžąàž‡", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "àž§àžČàž‡àžȘàžČàžą", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "àž­àž­àž", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "àč„àžĄàž„àčŒàž›àžŽàž”àž­àžąàžčàčˆ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "àč„àžĄàž„àčŒàč€àž›àžŽàž”àž­àžąàžčàčˆ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "àžàžČàžŁàžȘàčˆàž‡àč€àžȘàž”àžąàž‡àč€àžŁàž”àžąàžàžȘàžČàžąàč€àž›àžŽàž”àž­àžąàžčàčˆ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "àžàžČàžŁàžȘàčˆàž‡àč€àžȘàž”àžąàž‡àč€àžŁàž”àžąàžàžȘàžČàžąàž›àžŽàž”àž­àžąàžčàčˆ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "àžàžČàžŁàž•àž±àč‰àž‡àž„àčˆàžČ", @@ -3468,13 +3668,25 @@ "messageformat": "àč‚àž—àžŁàč€àž•àč‡àžĄàžˆàž­", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "àžȘàž„àž±àžšàč€àž›àč‡àž™àžĄàžžàžĄàžĄàž­àž‡àž•àžČàžŁàžČàž‡", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "àč€àž›àž„àž”àčˆàžąàž™àžĄàžžàžĄàžĄàž­àž‡", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "àžȘàž„àž±àžšàč€àž›àč‡àž™àžĄàžžàžĄàžĄàž­àž‡àžœàžčàč‰àžžàžčàž”", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "àžĄàžžàžĄàžĄàž­àž‡àčàžšàžšàž•àžČàžŁàžČàž‡", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "àžĄàžžàžĄàžĄàž­àž‡àčàžšàžšàčàž–àžšàč€àž„àž·àčˆàž­àž™", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "àžĄàžžàžĄàžĄàž­àž‡àčàžšàžšàč€àž™àč‰àž™àžœàžčàč‰àžžàžčàž”", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "àč€àž›àž„àž”àčˆàžąàž™àžĄàžžàžĄàžĄàž­àž‡àčàž„àč‰àž§", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "àž­àž­àžàžˆàžČàžàžȘàžČàžą", @@ -3576,6 +3788,14 @@ "messageformat": "àž•àžàž„àž‡", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄàč„àž”àč‰", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "àžȘàžČàžĄàžČàžŁàž–àčàžàč‰àč„àž‚àž‚àč‰àž­àž„àž§àžČàžĄàž™àž”àč‰àč„àž”àč‰ {max,number} àž„àžŁàž±àč‰àž‡àč€àž—àčˆàžČàž™àž±àč‰àž™", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "àž‚àž­àž­àž àž±àžąàž„àžŽàž‡àžàčŒ sgnl: // àž™àž±àč‰àž™àč„àžĄàčˆàžȘàžĄàč€àž«àž•àžžàžȘàžĄàžœàž„!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "àžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "àč€àžàžŽàž”àž‚àč‰àž­àžœàžŽàž”àžžàž„àžČàž”àč€àžàž”àčˆàžąàž§àžàž±àžšàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰ àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčƒàžŠàč‰àžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž™àž”àč‰àžàž±àžšàžšàž±àžàžŠàž”àž‚àž­àž‡àž„àžžàž“àč„àž”àč‰àž­àž”àžàž•àčˆàž­àč„àž›", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "àž„àžšàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "àžȘàžŁàč‰àžČàž‡àžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "àž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž”àž«àžŁàž·àž­àž„àžŽàž‡àžàčŒ", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "àžˆàžłàč€àž›àč‡àž™àž•àč‰àž­àž‡àžŁàž”àč€àž‹àč‡àž•àžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "àžˆàžłàč€àž›àč‡àž™àž•àč‰àž­àž‡àžŁàž”àč€àž‹àč‡àž•àž„àžŽàž‡àžàčŒàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "àčàžŠàžŁàčŒàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž‚àž­àž‡àž„àžžàž“", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "àž„àžšàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "àžàžČàžŁàž”àžłàč€àž™àžŽàž™àžàžČàžŁàž™àž”àč‰àžˆàž°àž„àžšàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž‚àž­àž‡àž„àžžàž“àčàž„àž°àž—àžłàčƒàž«àč‰àžœàžčàč‰àčƒàžŠàč‰àžŁàžČàžąàž­àž·àčˆàž™àž™àžłàč„àž›àčƒàžŠàč‰àč„àž”àč‰ àž„àžžàž“àčàž™àčˆàčƒàžˆàž«àžŁàž·àž­àč„àžĄàčˆ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "àžàžČàžŁàž”àžłàč€àž™àžŽàž™àžàžČàžŁàž™àž”àč‰àžˆàž°àž„àžšàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰àž‚àž­àž‡àž„àžžàž“ àžŁàž§àžĄàž—àž±àč‰àž‡àžąàžàč€àž„àžŽàžàž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž”àčàž„àž°àž„àžŽàž‡àžàčŒàč€àž”àžŽàžĄàž‚àž­àž‡àž„àžžàž“ àč‚àž”àžąàžœàžčàč‰àčƒàžŠàč‰àž„àž™àž­àž·àčˆàž™àžˆàž°àžȘàžČàžĄàžČàžŁàž–àž™àžłàžŠàž·àčˆàž­ “{username}” àč„àž›àčƒàžŠàč‰àč„àž”àč‰ àž•àč‰àž­àž‡àžàžČàžŁàž”àžłàč€àž™àžŽàž™àžàžČàžŁàž•àčˆàž­àž«àžŁàž·àž­àč„àžĄàčˆ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "àž„àžžàž“àžˆàž°àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àčàžŠàžŁàčŒàž«àžŁàž·àž­àž”àžčàžȘàž•àž­àžŁàž”àčˆàč„àž”àč‰àž­àž”àžàž•àčˆàž­àč„àž› àžàžČàžŁàž­àž±àž›àč€àž”àž•àžȘàž•àž­àžŁàž”àčˆàž—àž”àčˆàž„àžžàž“àč€àžžàžŽàčˆàž‡àčàžŠàžŁàčŒàžˆàž°àž–àžčàžàž„àžšàž”àč‰àž§àžąàč€àžŠàčˆàž™àžàž±àž™", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "àž àžČàž©àžČ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "àž àžČàž©àžČ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "àž àžČàž©àžČàž‚àž­àž‡àžŁàž°àžšàžš", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "àž„àč‰àž™àž«àžČàž àžČàž©àžČ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "àč„àžĄàčˆàžžàžšàžœàž„àž„àž±àžžàž˜àčŒàžȘàžłàž«àžŁàž±àžš “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "àčƒàžŠàč‰àž‡àžČàž™", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "àžŁàž”àžȘàž•àžČàžŁàčŒàž— Signal àč€àžžàž·àčˆàž­àčƒàžŠàč‰àž‡àžČàž™", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "àžˆàžłàč€àž›àč‡àž™àž•àč‰àž­àž‡àžŁàž”àžȘàž•àžČàžŁàčŒàž—àčàž­àž›àč€àžžàž·àčˆàž­àč€àž›àž„àž”àčˆàžąàž™àž àžČàž©àžČ", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "àžŁàž”àžȘàž•àžČàžŁàčŒàž—", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "àž›àžŁàž±àžšàžŁàžžàčˆàž™àč€àž›àč‡àž™ {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "àč€àžàžŽàž”àž‚àč‰àž­àžœàžŽàž”àžžàž„àžČàž”àž‚àž“àž°àžšàž±àž™àž—àž¶àžàžàžČàžŁàž•àž±àč‰àž‡àž„àčˆàžČàž‚àž­àž‡àž„àžžàž“ àč‚àž›àžŁàž”àž„àž­àž‡àž­àž”àžàž„àžŁàž±àč‰àž‡", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "àž‚àč‰àž­àž„àž§àžČàžĄ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "àžŁàžčàž›àčàžšàžšàž­àž·àčˆàž™àč†", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "àžŁàž”àč€àž‹àč‡àž•", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "àč€àžȘàžŁàč‡àžˆàžȘàžŽàč‰àž™", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "àžȘàž”àž„àžŽàž‡àžàčŒàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰, {index,number} àžˆàžČàž {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "àž«àžČàžàž„àžžàž“àžŁàž”àč€àž‹àč‡àž•àž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž” àž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž”àčàž„àž°àž„àžŽàž‡àžàčŒàž—àž”àčˆàžĄàž”àž­àžąàžčàčˆàč€àž”àžŽàžĄàž‚àž­àž‡àž„àžžàž“àžˆàž°àčƒàžŠàč‰àž‡àžČàž™àč„àžĄàčˆàč„àž”àč‰àž­àž”àžàž•àčˆàž­àč„àž›", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "àžàžłàž„àž±àž‡àžŁàž”àč€àž‹àč‡àž•àž„àžŽàž‡àžàčŒâ€Š", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "àžąàž±àž‡àč„àžĄàčˆàč„àž”àč‰àž•àž±àč‰àž‡àž„àčˆàžČàž„àžŽàž§àž­àžČàžŁàčŒàč‚àž„àč‰àž”àčàž„àž°àž„àžŽàž‡àžàčŒ àč‚àž›àžŁàž”àž•àžŁàž§àžˆàžȘàž­àžšàžàžČàžŁàč€àžŠàž·àčˆàž­àžĄàž•àčˆàž­àč€àž„àžŁàž·àž­àž‚àčˆàžČàžąàčàž„àč‰àž§àž„àž­àž‡àž­àž”àžàž„àžŁàž±àč‰àž‡", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "àž•àž±àč‰àž‡àž„àčˆàžČàžŠàž·àčˆàž­àžœàžčàč‰àčƒàžŠàč‰ Signal àž‚àž­àž‡àž„àžžàž“", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "àžȘàčˆàž‡àž­àž”àžàž„àžŁàž±àč‰àž‡", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "àžàžČàžŁàžàžŁàž°àž—àžłàč€àžžàžŽàčˆàžĄàč€àž•àžŽàžĄ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "àžàžČàžŁàč‚àž—àžŁ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "àžàžČàžŁàč‚àž—àžŁàčƒàž«àžĄàčˆ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "àžàžČàžŁàč‚àž—àžŁàčƒàž«àžĄàčˆ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "àžàžČàžŁàžàžŁàž°àž—àžłàč€àžžàžŽàčˆàžĄàč€àž•àžŽàžĄ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "àž„àč‰àžČàž‡àž›àžŁàž°àž§àž±àž•àžŽàžàžČàžŁàč‚àž—àžŁ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "àž„àč‰àžČàž‡àž›àžŁàž°àž§àž±àž•àžŽàžàžČàžŁàč‚àž—àžŁàčƒàžŠàčˆàž«àžŁàž·àž­àč„àžĄàčˆ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "àžàžČàžŁàž”àžłàč€àž™àžŽàž™àžàžČàžŁàž™àž”àč‰àžˆàž°àž„àžšàž›àžŁàž°àž§àž±àž•àžŽàžàžČàžŁàč‚àž—àžŁàž—àž±àč‰àž‡àž«àžĄàž”àž­àžąàčˆàžČàž‡àž–àžČàž§àžŁ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "àž„àč‰àžČàž‡", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "àž„àč‰àžČàž‡àž›àžŁàž°àž§àž±àž•àžŽàžàžČàžŁàč‚àž—àžŁàčàž„àč‰àž§", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "àž„àž„àžŽàžàč€àžžàž·àčˆàž­àž”àžčàž«àžŁàž·àž­àč€àžŁàžŽàčˆàžĄàžàžČàžŁàč‚àž—àžŁ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "àž„àč‰àž™àž«àžČ", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "àžàžŁàž­àž‡àč€àž‰àžžàžČàž°àžȘàžČàžąàž—àž”àčˆàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "àžȘàž„àž±àžš", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "àžąàž±àž‡àč„àžĄàčˆàžĄàž”àžàžČàžŁàč‚àž—àžŁàž„àčˆàžČàžȘàžžàž” àč€àžŁàžŽàčˆàžĄàž•àč‰àž™àž”àč‰àž§àžąàžàžČàžŁàč‚àž—àžŁàž«àžČàč€àžžàž·àčˆàž­àž™àž‚àž­àž‡àž„àžžàž“", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "àč„àžĄàčˆàžžàžšàžœàž„àž„àž±àžžàž˜àčŒàžȘàžłàž«àžŁàž±àžš “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "àč‚àž—àžŁàč€àž‚àč‰àžČ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "àč‚àž—àžŁàž­àž­àž", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "àč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "àč‚àž—àžŁàžàž„àžžàčˆàžĄ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "àžąàž±àž‡àč„àžĄàčˆàžĄàž”àžàžČàžŁàžȘàž™àž—àž™àžČàž„àčˆàžČàžȘàžžàž”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "àč„àžĄàčˆàžžàžšàžœàž„àž„àž±àžžàž˜àčŒàžȘàžłàž«àžŁàž±àžš “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {àžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡àž‚àžČàž­àž­àž} other {àžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡àž‚àžČàč€àž‚àč‰àžČ}}} Video {{direction, select, Outgoing {àžȘàžČàžąàž§àžŽàž”àž”àč‚àž­àč‚àž—àžŁàž­àž­àž} other {àžȘàžČàžąàž§àžŽàž”àž”àč‚àž­àč€àžŁàž”àžąàžàč€àž‚àč‰àžČ}}} Group {{direction, select, Outgoing {àžȘàžČàžąàč‚àž—àžŁàžàž„àžžàčˆàžĄàž‚àžČàž­àž­àž} other {àžȘàžČàžąàč‚àž—àžŁàžàž„àžžàčˆàžĄàž‚àžČàč€àž‚àč‰àžČ}}} other {{direction, select, Outgoing {àžȘàžČàžąàč‚àž—àžŁàž­àž­àž} other {àžȘàžČàžąàč‚àž—àžŁàč€àž‚àč‰àžČ}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {àžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡àž—àž”àčˆàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš} Video {àč‚àž—àžŁàž§àžŽàž”àž”àč‚àž­àž—àž”àčˆàžžàž„àžČàž”} Group {àžȘàžČàžąàč‚àž—àžŁàžàž„àžžàčˆàžĄàž—àž”àčˆàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš} other {àžȘàžČàžąàž—àž”àčˆàžžàž„àžČàž”}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {àžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡àž—àž”àčˆàž›àž„àžČàžąàžȘàžČàžąàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš} Video {àč‚àž—àžŁàž§àžŽàž”àž”àč‚àž­àž—àž”àčˆàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš} Group {àžàžČàžŁàč‚àž—àžŁàžàž„àžžàčˆàžĄàž—àž”àčˆàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš} other {àžàžČàžŁàč‚àž—àžŁàž—àž”àčˆàč„àžĄàčˆàč„àž”àč‰àžŁàž±àžš}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {àžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡àž—àž”àčˆàž–àžčàžàž›àžàžŽàč€àžȘàž˜} Video {àž§àžŽàž”àž”àč‚àž­àž„àž­àž„àž—àž”àčˆàž–àžčàžàž›àžàžŽàč€àžȘàž˜} Group {àžàžČàžŁàč‚àž—àžŁàžàž„àžžàčˆàžĄàž—àž”àčˆàž–àžčàžàž›àžàžŽàč€àžȘàž˜} other {àžàžČàžŁàč‚àž—àžŁàž—àž”àčˆàž–àžčàžàž›àžàžŽàč€àžȘàž˜}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {àž­àž”àž {count,number} àž„àž™àžàžłàž„àž±àž‡àžžàžŽàžĄàžžàčŒ}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "àžŸàž”àč€àžˆàž­àžŁàčŒàčàž„àž°àžšàžŁàžŽàžàžČàžŁàčƒàž«àžĄàčˆàč†", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "àžĄàž”àžàžČàžŁàž›àžŁàž±àžšàč€àž›àž„àž”àčˆàžąàž™àč€àž„àč‡àžàž™àč‰àž­àžą àžžàžŁàč‰àž­àžĄàčàžàč‰àč„àž‚àžšàž±àčŠàž àčàž„àž°àžàžČàžŁàžžàž±àž’àž™àžČàž›àžŁàž°àžȘàžŽàž—àž˜àžŽàž àžČàžžàčƒàž«àč‰àž”àž”àžąàžŽàčˆàž‡àž‚àž¶àč‰àž™ àž‚àž­àž‚àž­àžšàž„àžžàž“àž—àž”àčˆàč€àž„àž·àž­àžàčƒàžŠàč‰ Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "àžàžČàžŁàž­àž±àž›àč€àž”àž•àž„àžŁàž±àč‰àž‡àž™àž”àč‰àžĄàžČàžžàžŁàč‰àž­àžĄàžàžČàžŁàžžàž±àž’àž™àžČàčàžàč‰àč„àž‚àč€àžàž”àčˆàžąàž§àžàž±àžšàžàžČàžŁàč‚àž—àžŁàč€àžȘàž”àžąàž‡àčàž„àž°àž§àžŽàž”àž”àč‚àž­àž„àž­àž„ àžŁàž§àžĄàž–àž¶àž‡àžàžČàžŁàž›àžŁàž±àžšàž›àžŁàžžàž‡àžŁàž°àžšàžšàč€àžàč‡àžšàžšàž±àž™àž—àž¶àžàčƒàž™àžšàžČàž‡àžˆàžžàž” (àž‚àž­àžšàž„àžžàž“ {linkToGithub}!)" + "icu:WhatsNew__v6.39--0": { + "messageformat": "àčƒàž«àč‰àž„àžžàž“àč€àž›àž„àž”àčˆàžąàž™àž àžČàž©àžČàž—àž”àčˆàčàžȘàž”àž‡àčƒàž™àčàž­àž› Signal àčàžšàžšàž‡àčˆàžČàžąàč† àč€àž„àž·àž­àžàč„àž”àč‰àž•àžČàžĄàčƒàžˆàč„àžĄàčˆàž§àčˆàžČàžŁàž°àžšàžšàž‚àž­àž‡àč€àž„àžŁàž·àčˆàž­àž‡àžˆàž°àčƒàžŠàč‰àž àžČàž©àžČàž­àž°àč„àžŁàž­àžąàžčàčˆ (àč„àž›àž—àž”àčˆàžàžČàžŁàž•àž±àč‰àž‡àž„àčˆàžČ Signal > àž„àž±àžàž©àž“àž° > àž àžČàž©àžČ)" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "àč€àžŁàžČàž­àž±àž›àč€àž”àž•àč„àž­àž„àž­àž™àčƒàž™àžàžČàžŁàčàžˆàč‰àž‡àč€àž•àž·àž­àž™àžàž„àžžàčˆàžĄàžšàžČàž‡àž•àž±àž§" + "icu:WhatsNew__v6.39--1": { + "messageformat": "àč€àžŁàžČàžˆàž±àž”àžàžČàžŁàčàžàč‰àč„àž‚àž›àž±àžàž«àžČàž—àž”àčˆàž­àžČàžˆàč€àž„àžąàž—àžłàčƒàž«àč‰àžœàžčàč‰àčƒàžŠàč‰ macOS àč€àžˆàž­àžàž±àžšàž„àž§àžČàžĄàž„àčˆàžČàžŠàč‰àžČàč€àž„àč‡àžàž™àč‰àž­àžąàč€àž§àž„àžČàč€àž‚àč‰àžČàžŁàčˆàž§àžĄàžàžČàžŁàč‚àž—àžŁ" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "àč€àžŁàžČàž›àžŁàž±àžšàž›àžŁàžžàž‡àžŁàžčàž›àčàžšàžšàž‚àž­àž‡àžàžČàžŁàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àčƒàž™àž•àž­àž™àž—àž”àčˆàžȘàžĄàžČàžŠàžŽàžàč€àž‚àč‰àžČàžŁàčˆàž§àžĄàž«àžŁàž·àž­àž­àž­àžàžˆàžČàžàžȘàžČàžąàž§àžŽàž”àž”àč‚àž­àž„àž­àž„àžàž„àžžàčˆàžĄ" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "àžžàž±àž’àž™àžČàčƒàž«àč‰àž„àžžàž“àžȘàžČàžĄàžČàžŁàž–àž„àž„àžŽàžàž—àž”àčˆàžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàž«àžŁàž·àž­àž àžČàžžàž›àžŁàž°àžˆàžłàž•àž±àž§àžàž„àžžàčˆàžĄàžˆàžČàžàž•àžŁàž‡àčàž–àžšàž”àč‰àžČàž™àžšàž™àž‚àž­àž‡àčàžŠàž— àč€àžžàž·àčˆàž­àč€àž‚àč‰àžČàž–àž¶àž‡àžàžČàžŁàž•àž±àč‰àž‡àž„àčˆàžČàčàžŠàž—àč„àž”àč‰àž—àž±àž™àž—àž” àž—àž±àč‰àž‡àžąàž±àž‡àžȘàžČàžĄàžČàžŁàž–àč€àž›àžŽàž”àž”àžčàžȘàž•àž­àžŁàž”àčˆàčƒàž«àžĄàčˆàčƒàž™àčàžŠàž—àž™àž±àč‰àž™àč„àž”àč‰àč€àž„àžąàž­àž”àžàž”àč‰àž§àžą àž‚àž­àžšàž„àžžàž“ {linkToGithub} àžȘàžłàž«àžŁàž±àžšàžàžČàžŁàž›àžŁàž±àžšàž›àžŁàžžàž‡àž„àžŁàž±àč‰àž‡àž™àž”àč‰!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/tl-PH/messages.json b/_locales/tl-PH/messages.json index 2c17ddc0ad..ce205d87c0 100644 --- a/_locales/tl-PH/messages.json +++ b/_locales/tl-PH/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Database Error", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Nagkaroon ng database error. Pwede mong kopyahin ang error at kontakin ang Signal support para tulungan kang ayusin ang isyung ito. Kung kailangan mo nang gamitin ang Signal, pwede mong burahin ang iyong data at mag-restart.\n\nKontakin ang support: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "Burahin ang lahat ng data at i-restart", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Burahin ang data at mag-restart", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "Gusto mo bang permanenteng burahin ang lahat ng data?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Ang lahat ng message history at media mo ay permanenteng buburahin sa device na ito. Pwede mong gamitin ang Signal sa device na ito pagkatapos mo itong i-relink. Hindi nito buburahin ang anumang data sa phone mo.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Hindi magka-match ang version ng database mo at ang version na ito ng Signal. Siguraduhing buksan ang pinakabagong version ng Signal sa computer mo.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&File", @@ -300,6 +316,70 @@ "messageformat": "Chats", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Nagkaroon ng problema sa username mo, hindi na ito naka-assign sa iyong account. Maaari mong subukang ilagay ito ulit o pumili ng bago.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Ayusin", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Nagkaroon ng problema sa QR code mo at username link, hindi na ito valid. Gumawa ng bagong link para ma-share ito sa iba.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Ayusin", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Ipakita ang Tabs", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Itago ang Tabs", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Nagkaroon ng error", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} unread", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "I-mark as unread", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Chats", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Mga Tawag", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Stories", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Settings", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "I-update ang Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profile", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Bumalik", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Naka-archive ang chats na ito at lalabas lamang sa Inbox kapag may bagong natanggap na messages.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Call anyway", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Mag-join pa rin", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Continue call", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Ina-update ang safety numbers.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Matuto pa", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Naunang Safety number", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Susunod na Safety number", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Safety number version, {index,number} ng {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Markahan bilang verified", @@ -663,33 +747,41 @@ "messageformat": "Tanggalin ang verification", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Para i-verify ang end-to-end encryption n'yo ni {name}, pagkumparahin ang numbers sa itaas ng device n'ya. Pwede rin n'yang i-scan ang code mo sa device n'ya.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Matuto pa", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Para i-verify ang end-to-end encryption n'yo ni {name}, i-match ang color card na nasa itaas ng device n'ya at pagkumparahin ang numbers. Kung hindi magkapareho ang mga ito, subukan ang ibang pares ng safety numbers. Isang pares lang ang kailangan mag-match.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Para i-verify ang end-to-end encryption n'yo ni {name}, pagkumparahin ang numbers sa itaas ng device n'ya. Pwede rin n'yang i-scan ang code mo sa device n'ya.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Mga Pagbabago sa Safety Numbers", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Ina-update ang safety numbers sa loob ng transition period para ma-enable ang upcoming privacy features sa Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Para i-verify ang safety numbers, i-match ang color card sa device ng contact mo. Kung hindi magkapareho ang mga ito, subukan ang ibang pares ng safety numbers. Isang pares lang ang kailangan mag-match.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Kailangan mo ba ng tulong?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "OK", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Gagawa ng safety number para sa taong ito pagkatapos n'yong magpalitan ng messages.", @@ -1267,10 +1359,6 @@ "messageformat": "I-view ang recent media", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Para i-verify ang security ng end-to-end encryption n'yo ni {name}, pagkumparahin ang numbers sa itaas sa device n'ya. Pwede rin n'yang i-scan ang qr code sa itaas.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Hindi mo pa nakaka-chat ang contact na ito. Magiging available ang safety number mo sa kanya pagkatapos maipadala ang unang mensahe." }, @@ -1334,17 +1422,17 @@ "messageformat": "Info", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Burahin", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Burahin ang message", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Gusto mo bang burahin ang chat?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Gusto mo bang burahin ang message?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Mabubura ang chat mula sa device na ito.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Buburahin mula sa device na ito ang lahat ng messages sa chat na ito. Pwede mo pa ring i-search ang chat na ito pagkatapos mong magbura ng message.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Umalis sa group", @@ -1438,6 +1526,14 @@ "messageformat": "Naka-merge dito ang iyong message history sa parehong chats.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "Kay {conversationTitle} ang {phoneNumber}. Pareho kayong members ng {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "Kay {conversationTitle} ang {phoneNumber}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Thumbnail of image mula sa quoted message", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Muling Tumawag", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Simulan ang Call", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Mag-join sa Call", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Naka-mute ang microphone dahil sa marami ang nasa call", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Call notifications", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Puno na ang call", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Camera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Sumali", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Tumawag", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Puno na ang call", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Disabled ang camera", @@ -1621,10 +1725,6 @@ "messageformat": "Turn on camera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "I-mute", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microphone disabled", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "I-unmute ang mic", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Ibahagi", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Presenting disabled", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Stop presenting", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ring", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Ang group ay masyadong malaki para tawagan ang participants.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Enable ringing", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "I-off ang pag-ring", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "I-on ang pag-ring", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Karagdagang options", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Ikaw", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Naka-off ang camera mo", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Tingnan ang Safety Number", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Message", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Tingnan ang Safety Number", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Failed to fetch phone number. I-check ang iyong internet connection at subukan ulit.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Mayroon ka lang 3 oras para i-edit ang message pagkatapos mo itong i-send.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "May 3 oras ka lang para i-edit ang message pagkatapos mo itong i-send.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Nabura na ang mensaheng ito.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Masyadong malaki ang attachment para i-display.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Masyadong malaki ang ilang attachments para i-display.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Hindi makuha ang donation details", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Sa Signal beta lang", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Available lang sa Signal beta users ang pag-edit ng messages. Kung mag-edit ka ng message, ang mga taong may latest version lang ng Signal beta ang makakakita nito.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "I-edit ang message", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Kung mag-edit ka ng message, ang mga taong may latest versions lang ng Signal ang makakakita nito. Makikita nilang nag-edit ka ng message.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Incoming video call
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Outgoing voice call", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Outgoing video call", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "Tinatawagan ka ni {ringer}", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Nagre-reconnect
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} person} other {{count,number} people}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Audio call", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Ibaba", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Umalis", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Naka-off ang mic", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Naka-on ang mic", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Naka-on ang pag-ring", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Naka-off ang pag-ring", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Settings", @@ -3468,13 +3668,25 @@ "messageformat": "I-fullscreen ang call", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Mag-switch sa grid view", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Palitan ang view", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Mag-switch sa speaker view", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Grid view", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Sidebar view", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Speaker view", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Updated na ang view", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Leave call", @@ -3576,6 +3788,14 @@ "messageformat": "Okay", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Hindi ma-edit ang message", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "{max,number} beses lang pwedeng i-edit ang message na 'to.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Sorry, walang sense ang sgnl:// link!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Username", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Nagkaroon ng problema sa username mo, hindi na ito naka-assign sa iyong account.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Burahin ang username", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Gumawa ng username", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR code o link", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Kailangang i-reset ang username", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Kailangang i-reset ang username link", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "I-share ang username mo", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Burahin ang username", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Matatanggal ang username mo dahil dito, at pwede na itong i-claim ng ibang users. Sigurado ka na ba?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Matatanggal ang username mo at madi-disable ang iyong QR code at link. Pagkatapos, pwede nang makuha ng ibang users ang username na \"{username}\". Sigurado ka ba?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Hindi ka na pwedeng mag-share o mag-view ng stories. Mabubura rin ang story updates na shinare mo.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Wika", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Wika", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "System Language", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Maghanap ng wika", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "Walang resulta para sa \"{searchTerm}\"", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "I-set", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "I-restart ang Signal para i-apply", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Para mabago ang wika, kailangang mag-restart ng app na ito.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "I-restart", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "I-update sa version {version} na available", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Nagkaroon ng error when saving your settings. Subukan ulit.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Message", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Iba pang styles", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "I-reset", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Tapos na", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Kulay ng username link, {index,number} ng {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Kapag ni-reset mo ang iyong QR code, hindi na gagana ang existing QR code at link mo.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Nire-reset ang link
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Hindi pa naka-set ang QR code at link. I-check ang iyong internet connection at subukan ulit.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "I-set up ang iyong Signal username", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "edited", + "messageformat": "In-edit", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "I-send ulit", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Iba pang actions", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Mga Tawag", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Bagong call", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Bagong call", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Iba pang actions", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "I-clear ang call history", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Gusto mo bang i-clear ang call history?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Permanenteng mabubura ang lahat ng call history dito", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Clear", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Call history cleared", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "I-click para makita o magsimula ng call", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Maghanap", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Missed calls lang ang ipakita", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Toggle", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Walang recent calls. Magsimula sa pamamagitan ng pagtawag sa kaibigan mo.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "Walang resulta para sa \"{query}\"", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Incoming", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Outgoing", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Missed", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Group call", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Walang recent conversations.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "Walang resulta para sa \"{query}\"", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Outgoing voice call} other {Incoming voice call}}} Video {{direction, select, Outgoing {Outgoing video call} other {Incoming video call}}} Group {{direction, select, Outgoing {Outgoing group call} other {Incoming group call}}} other {{direction, select, Outgoing {Outgoing call} other {Incoming call}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Missed voice call} Video {Missed video call} Group {Missed group call} other {Missed call}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {'Di nasagot na voice call} Video {Unanswered video call} Group {Unanswered group call} other {Unanswered call}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Declined voice call} Video {Declined video call} Group {Declined group call} other {Declined call}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ang nagta-type.} other {{count,number} ang nagta-type.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "what's new", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Dagdag na maliliit na pag-aayos, pag-alis ng bugs, at pagpapaganda ng takbo ng app. Maraming salamat sa paggamit ng Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Ang update na ito'y may ilang improvements para sa voice at video calls, at ilang minor documentation updates (maraming salamat, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Ngayon, pwede mo nang baguhin ang iyong napiling wika sa Signal nang hindi binabago ang system settings mo (Signal Settings > Appearance > Language)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "In-update namin ang ilang group notification icons." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Inayos namin ang maikling delay na nangyayari minsan sa macOS pagkatapos mag-join sa isang call lobby." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Inayos namin ang transition animation ng video tiles kapag may sumali o umalis sa group call." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Ngayon, pwede ka nang mag-click ng profile photo o group avatar sa chat header para ma-access agad ang chat settings o tignan ang unseen stories mula sa chat na ito. Maraming salamat, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/tr/messages.json b/_locales/tr/messages.json index 561989c1ae..8f82ed5e75 100644 --- a/_locales/tr/messages.json +++ b/_locales/tr/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Veritabanı hatası", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Bir veri tabanı hatası olußtu. Hatayı kopyalayıp sorunun giderilmesine yardımcı olmak için Signal destekle iletißime geçebilirsin. Signal'i hemen kullanman gerekiyorsa, verilerini silebilir ve yeniden baßlatabilirsin.\n\nƞu adresi ziyaret ederek destekle iletißime geçebilirsin: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "TĂŒm verileri sil ve yeniden baßlat", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "Verileri sil ve yeniden baßlat", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "TĂŒm veriler kalıcı olarak silinsin mi?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "TĂŒm mesaj geçmißin ve medyan bu cihazdan kalıcı olarak silinecektir. Signal'i yeniden bağladıktan sonra bu cihazda kullanabileceksin. Bu ißlem telefonundaki hiçbir veriyi silmez.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Veri tabanının sĂŒrĂŒmĂŒ Signal'in bu sĂŒrĂŒmĂŒyle eßleßmiyor. Bilgisayarında Signal'in en son sĂŒrĂŒmĂŒnĂŒ açtığından emin ol.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Dosya", @@ -300,6 +316,70 @@ "messageformat": "Sohbetler", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Kullanıcı adınla ilgili bir sorun olußtu, artık hesabına atanmamıß olarak görĂŒnĂŒyor. Kullanıcı adını tekrar ayarlamayı deneyebilir veya yeni bir tane seçebilirsin.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ƞimdi dĂŒzelt", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Kare kodun ve kullanıcı adı bağlantınla ilgili bir sorun olußtu, bağlantı artık geçerli değil. Baßkalarıyla paylaßılacak yeni bir bağlantı olußtur.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ƞimdi dĂŒzelt", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Sekmeleri Göster", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "Sekmeleri Gizle", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Bir hata olußtu", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} okunmamıß", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Okunmadı olarak ißaretlendi", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Sohbetler", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Aramalar", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "Hikayeler", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "Ayarlar", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal'i GĂŒncelle", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Profil", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Geri", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Bu sohbetler arßivlendi ve sadece yeni mesajlar alınırsa Gelen Kutusunda görĂŒnecekler.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Yine de ara", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Yine de katıl", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Aramaya Devam Et", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "GĂŒvenlik numaraları gĂŒncelleniyor.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Dahasını Ă¶ÄŸrenin", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "Önceki GĂŒvenlik Numarası", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Sonraki GĂŒvenlik Numarası", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "GĂŒvenlik numarası sĂŒrĂŒmĂŒ, {index,number} / {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Doğrulanmıß olarak ißaretle", @@ -663,33 +747,41 @@ "messageformat": "Doğrulamayı temizle", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} ile uçtan uca ßifrelemeyi doğrulamak için yukarıdaki sayıları onun cihazlarındakilerle karßılaßtır. Cihazlarıyla kodunu da tarayabilirler.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Daha fazla bilgi", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} ile uçtan uca ßifrelemeyi doğrulamak için yukarıdaki renk kartını cihazlarıyla eßleßtir ve sayıları karßılaßtır. Bunlar eßleßmezse diğer gĂŒvenlik numarası çiftini dene. Yalnızca bir çiftin eßleßmesi gereklidir.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} ile uçtan uca ßifrelemeyi doğrulamak için yukarıdaki sayıları onun cihazlarındakilerle karßılaßtır. Cihazlarıyla kodunu da tarayabilirler.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "GĂŒvenlik Numaralarındaki Değißiklikler", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "GĂŒvenlik numaraları, Signal'de yakında kullanıma sunulacak olan gizlilik özelliklerini etkinleßtirmek için bir geçiß döneminde gĂŒncellenmektedir.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "GĂŒvenlik numaralarını doğrulamak için renk kartını kißinin cihazıyla eßleßtir. Bunlar eßleßmezse diğer gĂŒvenlik numarası çiftini dene. Yalnızca bir çiftin eßleßmesi gereklidir.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Yardıma mı ihtiyacınız var?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Anladım", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Bu kißiyle mesaj alıßverißinde bulunmanın ardından, bu kißi için bir gĂŒvenlik numarası olußturulacaktır.", @@ -1267,10 +1359,6 @@ "messageformat": "Son içerikleri görĂŒntĂŒle", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} ile uçtan uca ßifrelemenin gĂŒvenliğini doğrulamak için yukarıdaki sayıları onun cihazlarındakilerle karßılaßtır. Yukarıdaki karekodu da tarayabilirler.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Bu kißiyle herhangi bir iletißimde bulunmadınız. GĂŒvenlik numaralarınız ilk iletiden sonra olußturulacaktır." }, @@ -1334,17 +1422,17 @@ "messageformat": "Bilgi", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Sil", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Mesajları sil", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "Sohbet silinsin mi?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Mesajları sil?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Bu sohbet, bu cihazdan silinecektir.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Bu sohbetteki mesajlar bu cihazdan silinecek. Mesajları sildikten sonra da bu sohbeti arayabilirsin.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Gruptan ayrıl", @@ -1438,6 +1526,14 @@ "messageformat": "Her iki sohbet için mesaj geçmißin burada birleßtirildi.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} , {conversationTitle} adlı kißiye aittir. İkiniz de {sharedGroup} grubunun ĂŒyesisiniz.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber}, {conversationTitle} adlı kißiye aittir", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "Alıntılanmıß iletideki görĂŒntĂŒnĂŒn önizlemesi", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Tekrar Ara", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Arama Baßlat", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Çağrıya Katıl", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Aramanın boyutundan dolayı mikrofon sessize alındı", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Arama bildirimleri", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Arama dolu", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Kamera", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Katıl", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "Baßlat", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Arama dolu", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Kamera devre dıßı", @@ -1621,10 +1725,6 @@ "messageformat": "Kamerayı aç", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "Sessiz", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Mikrofon devre dıßı", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Mikrofonu aç", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Paylaß", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "Sunum yapma devre dıßı", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Sunmayı durdur", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ara", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Grup, katılımcıların aranması için çok bĂŒyĂŒk.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Telefon çalmasını etkinleßtir", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Zil sesini kapat", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Zil sesini aç", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Daha fazla seçenek", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Sen", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Kameranız kapalı", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "GĂŒvenlik Numarasını görĂŒntĂŒle", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Mesaj", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "GĂŒvenlik Numarasını görĂŒntĂŒle", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "Telefon numarası alınamadı. Bağlantınızı kontrol edip tekrar deneyin.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "DĂŒzenlemeler yalnızca bu mesajı gönderdikten sonraki 3 saat içinde uygulanabilir.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "DĂŒzenlemeler yalnızca bu mesajı gönderdikten sonraki 24 saat içinde uygulanabilir.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Bu ileti silindi.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Ek, görĂŒntĂŒlenemeyecek kadar bĂŒyĂŒk.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Bazı ekler görĂŒntĂŒlenemeyecek kadar bĂŒyĂŒk.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "Bağıß ayrıntıları getirilemiyor", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Yalnızca Signal beta", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Mesajları dĂŒzenleme yalnızca Signal beta kullanıcıları tarafından kullanılabilir. Bir mesajı dĂŒzenlersen, dĂŒzenlemen yalnızca Signal beta'nın son sĂŒrĂŒmĂŒnĂŒ kullanan kißiler tarafından görĂŒlebilir.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Mesajı DĂŒzenle", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Bir mesajı dĂŒzenlersen yaptığın dĂŒzenleme yalnızca Signal'in son sĂŒrĂŒmlerini kullanan kißiler tarafından görĂŒlebilir. Bir mesajı dĂŒzenlediğini görebilecekler.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "Gelen görĂŒntĂŒlĂŒ arama
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Giden sesli arama", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Giden görĂŒntĂŒlĂŒ arama", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} sizi arıyor", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Yeniden bağlanıyor
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} kißi} other {{count,number} kißi}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Sesli arama", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Kapat", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Ayrıl", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Mikrofon kapalı", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Mikrofon açık", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Zil açık", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Zil kapalı", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "Ayarlar", @@ -3468,13 +3668,25 @@ "messageformat": "Aramayı tam ekran yap", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Izgara görĂŒnĂŒmĂŒne geç", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "GörĂŒnĂŒmĂŒ değißtir", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Konußmacı görĂŒnĂŒmĂŒne geç", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Izgara görĂŒnĂŒmĂŒ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Kenar çubuğu görĂŒnĂŒmĂŒ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Konußmacı görĂŒnĂŒmĂŒ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "GörĂŒnĂŒm gĂŒncellendi", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Aramadan ayrıl", @@ -3576,6 +3788,14 @@ "messageformat": "Tamam", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Mesaj dĂŒzenlenemiyor", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Bu mesaja yalnızca {max,number} dĂŒzenleme uygulanabilir.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ÖzĂŒr dileriz, bu sgnl:// bağlantısı anlaßılamadı!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Kullanıcı adı", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Kullanıcı adınla ilgili bir sorun olußtu, artık hesabına atanmamıß olarak görĂŒnĂŒyor.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Kullanıcı adını sil", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Kullanıcı adı Olußtur", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "Kare Kod veya Bağlantı", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Kullanıcı adının sıfırlanması gerekiyor", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Kullanıcı adı bağlantısının sıfırlanması gerekiyor", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Kullanıcı Adını Paylaß", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Kullanıcı adını sil", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Bu ißlem kullanıcı adını kaldırarak söz konusu adı diğer kullanıcılar tarafından kullanılabilir hĂąle getirecektir. Kaldırmak istiyor musun?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Bu ißlem, kullanıcı adını kaldırır ve kare kodunu ve bağlantını devre dıßı bırakır. \"{username}\" baßkalarının talebine açık olacaktır. Emin misin?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Artık hikaye paylaßamayacak veya görĂŒntĂŒleyemeyeceksin. Yakın zamanda paylaßtığın hikaye gĂŒncellemeleri de silinecek.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "Dil", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "Dil", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "Sistem Dili", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "Dilleri ara", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "\"{searchTerm}\" için sonuç yok", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Ayarla", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Uygulamak için Signal'i yeniden baßlat", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Dili değißtirmek için uygulamanın yeniden baßlatılması gerekiyor.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Yeniden baßlat", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} sĂŒrĂŒmĂŒne gĂŒncelleme mevcut", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Ayarlarınız kaydedilirken bir hata olußtu. LĂŒtfen daha sonra tekrar deneyin.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Mesaj", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Daha fazla model", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "Sıfırla", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Tamam", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "Kullanıcı adı bağlantı rengi, {index,number} / {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "Kare kodunu sıfırlarsan mevcut kare kodun ve bağlantın artık çalıßmaz.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Bağlantı sıfırlanıyor...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "Kare kodu ve bağlantı ayarlanmadı. Ağ bağlantını kontrol edip tekrar dene.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Signal kullanıcı adını ayarla", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "dĂŒzenlendi", + "messageformat": "DĂŒzenlendi", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Tekrar Gönder", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Diğer eylemler", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Aramalar", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Yeni arama", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Yeni arama", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Diğer eylemler", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Arama geçmißini temizle", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Arama geçmißi temizlensin mi?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Bu ißlem tĂŒm arama geçmißini kalıcı olarak siler", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Kaldır", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Arama geçmißi temizlendi", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Bir aramayı görĂŒntĂŒlemek veya baßlatmak için tıkla", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "Ara", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Kaçırılana göre filtrele", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Değißtir", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "GĂŒncel arama yok. Bir arkadaßını arayarak baßla.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "\"{query}\" için sonuç yok", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Gelen", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Giden", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Cevapsız", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Grup görĂŒĆŸmesi", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "GĂŒncel konußma yok.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "\"{query}\" için sonuç yok", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Giden sesli arama} other {Gelen sesli arama}}} Video {{direction, select, Outgoing {Giden görĂŒntĂŒlĂŒ arama} other {Gelen görĂŒntĂŒlĂŒ arama}}} Group {{direction, select, Outgoing {Giden grup araması} other {Gelen grup araması}}} other {{direction, select, Outgoing {Giden arama} other {Gelen arama}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Cevapsız sesli arama} Video {Cevapsız görĂŒntĂŒlĂŒ arama} Group {Cevapsız grup araması} other {Cevapsız arama}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Cevapsız sesli arama} Video {Cevaplanmamıß görĂŒntĂŒlĂŒ arama} Group {Grup araması cevaplanmadı} other {Arama cevaplanmadı}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Sesli arama reddedildi} Video {GörĂŒntĂŒlĂŒ arama reddedildi} Group {Grup araması reddedildi} other {Arama reddedildi}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} kißi daha yazıyor.} other {{count,number} kißi daha yazıyor.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Neler Yeni", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "KĂŒĂ§ĂŒk ince ayarlar, hata dĂŒzeltmeleri ve performans gelißtirmeleri yaptık. Signal'i kullandığın için teßekkĂŒrler!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "Bu gĂŒncelleme, sesli ve görĂŒntĂŒlĂŒ aramalar için birkaç iyileßtirmeden ve bazı kĂŒĂ§ĂŒk dokĂŒman gĂŒncellemelerinden olußmaktadır (teßekkĂŒrler, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Artık sistem ayarlarını (Signal Ayarları > GörĂŒnĂŒm > Dil) değißtirmeden Signal'de seçtiğin dili değißtirebilirsin." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Bazı grup bildirimi simgelerini gĂŒncelledik. Bu simgeler özellikle de Karanlık Tema'nın karanlığında yaßıyorsan, okunabilirliği artırmaya yardımcı olur. Önceden kullanılan simgeler yalnızca karanlık moda ayak uydurmaya çalıßıyordu. Bu yeni simgeler ise karanlığın içinde doğdu, onun tarafından ßekillendirildi." + "icu:WhatsNew__v6.39--1": { + "messageformat": "MacOS ĂŒzerinde bir arama lobisine katıldıktan sonra bazen meydana gelen kısa bir gecikmeyi dĂŒzelttik." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Birisi grup görĂŒĆŸmesine katıldığında veya grup görĂŒĆŸmesinden ayrıldığında video karelerinin geçiß animasyonunu dĂŒzelttik. Bir arkadaßının yĂŒzĂŒnĂŒn görĂŒĆŸ alanına kaydığını gördĂŒÄŸĂŒnde, bu heyecan verici bir andır." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Artık sohbet ayarlarına hızlı bir ßekilde erißmek veya bu sohbetteki görĂŒnmeyen hikayeleri görĂŒntĂŒlemek için sohbet baßlığındaki bir profil fotoğrafına veya grup avatarına tıklayabilirsin. TeßekkĂŒrler {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ug/messages.json b/_locales/ug/messages.json index 965b3e7933..89db789497 100644 --- a/_locales/ug/messages.json +++ b/_locales/ug/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ŰłŰ§Ù†ŰŻŰ§Ù† ۟ۧŰȘŰ§Ù„Ù‰Ù‚Ù‰", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ŰłŰ§Ù†ŰŻŰ§Ù†ŰŻŰ§ ۟ۧŰȘŰ§Ù„Ù‰Ù‚ ÙƒÛ†Ű±ÛˆÙ„ŰŻÙ‰. ۟ۧŰȘŰ§Ù„Ù‰Ù‚Ù†Ù‰ ÙƒÛ†Ú†ÛˆŰ±Ù‰Û‹Ű§Ù„Ű§Ù„Ű§ÙŠŰłÙ‰ŰČ Û‹Û• ŰŠÛ‡Ù†Ù‰ ŰŠÙˆÚ­ŰŽŰ§ŰŽ ŰŠÛˆÚ†ÛˆÙ† Signal ÙŠŰ§Ű±ŰŻÛ•Ù… ŰšÙ‰Ù„Û•Ù† ŰŠŰ§Ù„Ű§Ù‚Ù‰Ù„Ù‰ŰŽÙ‰Ú­. ŰŠÛ•ÚŻÛ•Ű± Signalنى ŰŻÛ•Ű±ÚŸŰ§Ù„ ŰŠÙ‰ŰŽÙ„Û•ŰȘمەكچى ŰšÙˆÙ„ŰłÙ‰Ú­Ù‰ŰČی ŰłŰ§Ù†Ù„Ù‰Ù‚ Ù…Û•Ù„Û‡Ù…Ű§ŰȘÙ„Ù‰Ű±Ù‰Ú­Ù‰ŰČنى ŰŠÛ†Ú†ÛˆŰ±ÛˆÙŸŰŒ Ù‚Ű§ÙŠŰȘۧ قوŰČŰșۧŰȘŰłÙ‰Ú­Ù‰ŰČ ŰšÙˆÙ„Ù‰ŰŻÛ‡.\n\nÙŠŰ§Ű±ŰŻÛ•Ù… ŰŠŰ§Ù„Ű§Ù‚Ù‰Ù„Ù‰ŰŽÙ‰ŰŽ ŰŠÛ‡ŰłÛ‡Ù„Ù‰:{link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ŰšŰ§Ű±Ù„Ù‰Ù‚ ŰłŰ§Ù†Ù„Ù‰Ù‚ Ù…Û•Ù„Û‡Ù…Ű§ŰȘÙ„Ű§Ű±Ù†Ù‰ ŰŠÛ†Ú†ÛˆŰ±ÛˆÙŸ Ù‚Ű§ÙŠŰȘۧ قوŰČŰșىŰȘÙ‰ŰŽ", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ŰłŰ§Ù†Ù„Ù‰Ù‚ Ù…Û•Ù„Û‡Ù…Ű§ŰȘÙ„Ű§Ű±Ù†Ù‰ ŰŠÛ†Ú†ÛˆŰ±ÛˆÙŸŰŒ Ù‚Ű§ÙŠŰȘۧ قوŰČŰșىŰȘÙ‰ŰŽ", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ŰłŰ§Ù†Ù„Ù‰Ù‚ Ù…Û•Ù„Û‡Ù…Ű§ŰȘÙ„Ű§Ű±Ù†Ù‰ ÙŸÛˆŰȘۈنلەي ŰŠÛ†Ú†ÛˆŰ±Û•Ù…ŰłÙ‰ŰČ۟", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ŰšŰ§Ű±Ù„Ù‰Ù‚ ŰŠÛ‡Ú†Û‡Ű± ۟ۧŰȘÙ‰Ű±Ù‰Ú­Ù‰ŰČ Û‹Û• Ù…ÛŰŻÙŠŰ§Ù„Ù‰Ű±Ù‰Ú­Ù‰ŰČ ŰšÛ‡ ŰŠÛˆŰłÙƒÛˆÙ†Ù‰ŰŻÙ‰Ù† Ù…Û•Ú­ÚŻÛˆÙ„ÛˆÙƒÙƒÛ• ŰŠÛ†Ú†ÛˆŰ±Ù‰Ù„Ù‰Û‹ÛŰȘÙ‰ŰŻÛ‡. ŰŠÛ‡Ù†Ù‰ Ù‚Ű§ÙŠŰȘۧ ŰŠÛ‡Ù„Ù‰ŰșŰ§Ù†ŰŻÙ‰Ù† كېيىن Signalنى ŰšÛ‡ ŰŠÛˆŰłÙƒÛˆÙ†Ù‰ŰŻÛ• ŰŠÙ‰ŰŽÙ„Ù‰ŰȘÛ•Ù„Û•ÙŠŰłÙ‰ŰČ. ŰšÛ‡ ŰłÙ‰ŰČنىڭ ŰȘېلېفونىڭىŰČŰŻÙ‰ÙƒÙ‰ ÚŸÛÚ†Ù‚Ű§Ù†ŰŻŰ§Ù‚ ŰłŰ§Ù†Ù„Ù‰Ù‚ Ù…Û•Ù„Û‡Ù…Ű§ŰȘنى ŰŠÛ†Ú†ÛˆŰ±Ù…Û•ÙŠŰŻÛ‡.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "ŰłÙ‰ŰČنىڭ ŰłŰ§Ù†ŰŻŰ§Ù†Ù‰Ú­Ù‰ŰČنىڭ Ù†Û•ŰŽŰ±Ù‰ Signalنىڭ ŰšÛ‡ Ù†Û•ŰŽŰ±Ù‰ÚŻÛ• Ù…Ű§Űł ÙƒÛ•Ù„Ù…Û•ÙŠŰŻÛ‡. كومٟيۇŰȘÛŰ±Ù‰Ú­Ù‰ŰČۯۧ Signalنىڭ ŰŠÛ•Ú­ يېڭى Ù†Û•ŰŽÙ‰Ű±Ù‰Ù†Ù‰ ŰŠÛÚ†Ù‰Û‹Ű§ŰȘÙ‚Ű§Ù†Ù„Ù‰Ù‚Ù‰Ú­Ù‰ŰČنى ŰŹÛ•ŰČÙ…Ù„Û•ŰŽŰȘÛˆŰ±ÛˆÚ­.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ÚŸÛ†ŰŹŰŹÛ•ŰȘ", @@ -300,6 +316,70 @@ "messageformat": "ÙŸŰ§Ű±Ű§Ú­", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ú­Ù‰ŰČۯۧ ۟ۧŰȘŰ§Ù„Ù‰Ù‚ ÙƒÛ†Ű±ÛˆÙ„ÚŻÛ•Ù† ŰšÙˆÙ„Û‡ÙŸŰŒ ŰŠÛ‡ ŰŠÛ•Ù…ŰŻÙ‰ ŰłÙ‰ŰČنىڭ ÚŸÛŰłŰ§ŰšŰ§ŰȘىڭىŰČŰșۧ ŰȘەۋە ŰŠÛ•Ù…Û•Űł. ŰŠÛ‡Ù†Ù‰ Ù‚Ű§ÙŠŰȘۧ ŰȘÛ•Ú­ŰŽÛ•ÙŸ ŰłÙ‰Ù†Ű§ÙŸ ŰšŰ§Ù‚ŰłÙ‰Ú­Ù‰ŰČ ÙŠŰ§ÙƒÙ‰ يېڭى ŰšÙ‰Ű± Ù†Ű§Ù… ŰȘŰ§Ù„Ù„Ù‰ŰłÙ‰Ú­Ù‰ŰČ ŰšÙˆÙ„Ù‰ŰŻÛ‡.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ŰŻÛ•Ű±ÚŸŰ§Ù„ ŰŠÙˆÚ­ŰŽŰ§ŰŽ", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "QR ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČ Û‹Û• ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰ ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰Ú­Ù‰ŰČۯۧ Ù…Û•ŰłÙ‰Ù„Û• ÙƒÛ†Ű±ÛˆÙ„ÚŻÛ•Ù† ŰšÙˆÙ„Û‡ÙŸŰŒ ŰŠÛ‡Ù„Ű§Ű± ŰŠÛ•Ù…ŰŻÙ‰ ŰŠÙ‰Ù†Ű§Û‹Û•ŰȘŰłÙ‰ŰČ. ŰšŰ§ŰŽÙ‚Ù‰Ù„Ű§Ű± ŰšÙ‰Ù„Û•Ù† ŰŠÙˆŰ±ŰȘŰ§Ù‚Ù„Ù‰ŰŽÙ‰ŰŽ ŰŠÛˆÚ†ÛˆÙ† يېڭى ŰŠÛ‡Ù„Ű§Ù†Ù…Ű§ Ù‚Û‡Ű±Û‡Ú­.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ŰŻÛ•Ű±ÚŸŰ§Ù„ ŰŠÙˆÚ­ŰŽŰ§ŰŽ", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ŰšÛ•ŰȘكۈچنى ÙƒÛ†Ű±ŰłÙ‰ŰȘÙ‰ŰŽ", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ŰšÛ•ŰȘكۈچنى ÙŠÙˆŰŽÛ‡Ű±Û‡ŰŽ", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "۟ۧŰȘŰ§Ù„Ù‰Ù‚ ÙƒÛ†Ű±ÛˆÙ„ŰŻÙ‰", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} ŰŠÙˆÙ‚Û‡Ù„Ù…Ù‰ŰșŰ§Ù† ŰŠÛ‡Ú†Û‡Ű±", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ŰŠÙˆÙ‚Û‡Ù„Ù…Ù‰ŰșŰ§Ù† ŰŻÛ•ÙŸ ŰšÛ•Ù„ÚŻÛ• قويۇلŰșŰ§Ù†", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "ÙŸŰ§Ű±Ű§Ú­", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰ŰŽÙ„Ű§Ű±", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ÚŸÛÙƒŰ§ÙŠÙ‰Ù„Û•Ű±", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ŰȘÛ•Ú­ŰŽÛ•ÙƒÙ„Û•Ű±", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal نى ÙŠÛÚ­Ù‰Ù„Ű§", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ŰŠŰ§Ű±ŰźÙ‰ÙŸ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Ù‚Ű§ÙŠŰȘ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "ŰšÛ‡ ÙŸŰ§Ű±Ű§Ú­Ù„Ű§Ű± ŰŠŰ§Ű±ŰźÙ‰ÙŸÙ„Ű§ŰŽŰȘÛ‡Ű±Û‡Ù„ŰŻÙ‰ŰŒ ÙŸÛ•Ù‚Û•ŰȘ يېڭى ŰŠÛ‡Ú†Û‡Ű± ŰȘŰ§ÙŸŰŽÛ‡Ű±Û‡Û‹Ű§Ù„ŰșŰ§Ù†ŰŻŰ§ Ù‚ÙˆŰšÛ‡Ù„Ù„Ű§ŰŽ ŰłŰ§Ù†ŰŻÛ‡Ù‚Ù‰ŰŻŰ§ ÙƒÛ†Ű±ÛˆÙ†Ù‰ŰŻÛ‡.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Û‹Û•Ű±", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ÙŠÛ•Ù†Ù‰Ù„Ű§ Ù‚ÙˆŰŽÛ‡Ù„Û‡Ú­", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ŰŻŰ§Û‹Ű§Ù…Ù„Ù‰Ù‚ Ú†Ű§Ù‚Ù‰Ű±", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰ ÙŠÛÚ­Ù‰Ù„Ù‰Ù†Ù‰Û‹Ű§ŰȘÙ‰ŰŻÛ‡.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "ÙƒÛ†ÙŸŰ±Û•Ùƒ ŰŠÛ†ÚŻÙ‰Ù†Ù‰ŰŽ", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ŰŠŰ§Ù„ŰŻÙ‰Ù†Ù‚Ù‰ ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "كىيىنكى ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†Û‡Ù…Û‡Ű± Ù†Û•ŰŽÙ‰Ű±Ù„Ù‰Ű±Ù‰ŰŒ {index,number}نىڭ{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ŰŻÛ•Ù„Ù‰Ù„Ù„Û•Ù†ŰŻÙ‰ ŰšÛ•Ù„ÚŻÙ‰ŰłÙ‰ ŰłŰ§Ù„", @@ -663,33 +747,41 @@ "messageformat": "ŰŻÛ•Ù„Ù‰Ù„Ù„Û•ŰŽÙ†Ù‰ ŰȘۧŰČÙ‰Ù„Ű§", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "«{name}» ŰšÙ‰Ù„Û•Ù† ŰŠÛ‡Ú†ŰȘىن ŰŠÛ‡Ú†Ù‚Ű§ Ù…Û•ŰźÙŸÙ‰ÙŠÙ„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽÙ†Ù‰ ŰŹÛ•ŰČÙ‰Ù…Ù„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽ ŰŠÛˆÚ†ÛˆÙ†ŰŒ ÙŠÛ‡Ù‚Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰ Ù†ÙˆÙ…Û‡Ű±Ù„Ű§Ű±Ù†Ù‰ ŰŠÛ‡Ù„Ű§Ű±Ù†Ù‰Ú­ ŰŠÛ•ŰłÛ‹Ű§ÙŸÙ„Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰Ù„Û•Ű± ŰšÙ‰Ù„Û•Ù† ŰłÛÙ„Ù‰ŰŽŰȘÛ‡Ű±Û‡Ú­. ŰŠÛ‡Ù„Ű§Ű±Ù…Û‡ ŰłÙ‰ŰČنىڭ ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČنى ŰŠÛ†ŰČÙ„Ù‰Ű±Ù‰Ù†Ù‰Ú­ ŰŠÛ•ŰłÛ‹Ű§ÙŸÙ„Ù‰Ű±Ù‰ ŰšÙ‰Ù„Û•Ù† ŰłÙƒŰ§Ù†Ù†ÛŰ±Ù„Ù‰ÙŠŰ§Ù„Ű§ÙŠŰŻÛ‡.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "ŰȘÛ•ÙŸŰłÙ‰Ù„Ű§ŰȘى", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "«{name}» ŰšÙ‰Ù„Û•Ù† ŰŠÛ‡Ú†ŰȘىن ŰŠÛ‡Ú†Ù‚Ű§ Ù…Û•ŰźÙŸÙ‰ÙŠÙ„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽÙ†Ù‰ ŰŹÛ•ŰČÙ‰Ù…Ù„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽ ŰŠÛˆÚ†ÛˆÙ†ŰŒ ÙŠÛ‡Ù‚Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰ Ű±Û•Ú­ ÙƒŰ§Ű±ŰȘÙ„Ù‰Ű±Ù‰Ù†Ù‰ ŰŠÛ‡Ù„Ű§Ű±Ù†Ù‰Ú­ ŰŠÛ•ŰłÛ‹Ű§ÙŸÙ„Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰Ù„Û•Ű± ŰšÙ‰Ù„Û•Ù† Ù…Ű§ŰłÙ„Ű§ŰŽŰȘÛ‡Ű±Û‡Ú­. ŰŠÛ•ÚŻÛ•Ű± ŰšÛ‡Ù„Ű§Ű± Ù…Ű§ŰłÙ„Ű§ŰŽÙ…Ù‰ŰłŰ§ŰŒ ŰšŰ§ŰŽÙ‚Ű§ ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù„Ù‰Ű±Ù‰Ù†Ù‰ ŰłÙ‰Ù†Ű§Ú­. ÙŸÛ•Ù‚Û•ŰȘ ŰšÙ‰Ű± ŰŹÛˆÙŸ Ù†ÙˆÙ…Û‡Ű±Ù†Ù‰Ú­ Ù…Ű§ŰłÙ„Ù‰ŰŽÙ‰ŰŽÙ‰ ÙƒÛ‡ÙŸŰ§ÙŠÛ•.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "«{name}» ŰšÙ‰Ù„Û•Ù† ŰŠÛ‡Ú†ŰȘىن ŰŠÛ‡Ú†Ù‚Ű§ Ù…Û•ŰźÙŸÙ‰ÙŠÙ„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽÙ†Ù‰ ŰŹÛ•ŰČÙ‰Ù…Ù„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽ ŰŠÛˆÚ†ÛˆÙ†ŰŒ ÙŠÛ‡Ù‚Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰ Ù†ÙˆÙ…Û‡Ű±Ù„Ű§Ű±Ù†Ù‰ ŰŠÛ‡Ù„Ű§Ű±Ù†Ù‰Ú­ ŰŠÛ•ŰłÛ‹Ű§ÙŸÙ„Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰Ù„Û•Ű± ŰšÙ‰Ù„Û•Ù† ŰłÛÙ„Ù‰ŰŽŰȘÛ‡Ű±Û‡Ú­. ŰŠÛ‡Ù„Ű§Ű±Ù…Û‡ ŰłÙ‰ŰČنىڭ ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČنى ŰŠÛ†ŰČÙ„Ù‰Ű±Ù‰Ù†Ù‰Ú­ ŰŠÛ•ŰłÛ‹Ű§ÙŸÙ„Ù‰Ű±Ù‰ ŰšÙ‰Ù„Û•Ù† ŰłÙƒŰ§Ù†Ù†ÛŰ±Ù„Ù‰ÙŠŰ§Ù„Ű§ÙŠŰŻÛ‡.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰Ù†Ù‰ ŰŠÛ†ŰČÚŻÛ•Ű±ŰȘÙ‰ŰŽ", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal ŰŻÙ‰ÙƒÙ‰ يېڭى Ù…Û•ŰźÙŸÙ‰ÙŠÛ•ŰȘلىك ŰŠÙ‰Ù‚ŰȘÙ‰ŰŻŰ§Ű±Ù„Ù‰Ű±Ù‰Ù†Ù‰ قوŰČŰșىŰȘÙ‰ŰŽ ŰŠÛˆÚ†ÛˆÙ† ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰ ŰšÛ‡ ŰŠÛ†ŰȘكۈنچى مەŰČÚŻÙ‰Ù„ŰŻÛ• يېڭىلىنىٟ ŰšŰ§Ű±Ù‰ŰŻÛ‡.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù„Ù‰Ű±Ù‰Ù†Ù‰ ŰŹÛ•ŰČÙ‰Ù…Ù„Û•ŰŽŰȘÛˆŰ±ÛˆŰŽ ŰŠÛˆÚ†ÛˆÙ†ŰŒ Ű±Û•Ú­ ÙƒŰ§Ű±ŰȘÙ„Ù‰Ű±Ù‰Ù†Ù‰ ŰłÙ‰ŰČنىڭ ŰŠŰ§Ù„Ű§Ù‚Ù‰ŰŻŰ§ŰŽÙ„Ù‰Ű±Ù‰Ú­Ù‰ŰČنى ŰŠÛ•ŰłÛ‹Ű§ÙŸÙ„Ù‰Ű±Ù‰ ŰšÙ‰Ù„Û•Ù† Ù…Ű§ŰłÙ„Ű§ŰŽŰȘÛ‡Ű±Û‡Ú­. ŰŠÛ•ÚŻÛ•Ű± ŰšÛ‡Ù„Ű§Ű± Ù…Ű§ŰłÙ„Ű§ŰŽÙ…Ù‰ŰłŰ§ŰŒ ŰšŰ§ŰŽÙ‚Ű§ ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù„Ù‰Ű±Ù‰Ù†Ù‰ ŰłÙ‰Ù†Ű§Ú­. ÙŸÛ•Ù‚Û•ŰȘ ŰšÙ‰Ű± ŰŹÛˆÙŸ Ù†ÙˆÙ…Û‡Ű±Ù†Ù‰Ú­ Ù…Ű§ŰłÙ„Ù‰ŰŽÙ‰ŰŽÙ‰ ÙƒÛ‡ÙŸŰ§ÙŠÛ•.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ÙŠŰ§Ű±ŰŻÛ•Ù… ÙƒÛŰ±Û•ÙƒÙ…Û‡ŰŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ŰšÙ‰Ù„ŰŻÙ‰Ù…", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ŰšÛ‡ ÙƒÙ‰ŰŽÙ‰ ŰšÙ‰Ù„Û•Ù† ŰŠÛ‡Ú†Û‡Ű±Ù„Ű§ŰŽÙ‚Ű§Ù†ŰŻÙ‰Ù† كېيىن ŰšÙ‰Ű± ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰ ŰŽÛ•ÙƒÙ‰Ù„Ù„Ù‰Ù†Ù‰ŰŻÛ‡.", @@ -1267,10 +1359,6 @@ "messageformat": "يېقىنقى Ù…ÛŰŻÙ‰ÙŠŰ§Ù„Ű§Ű±Ù†Ù‰ ÙƒÛ†Ű±ÛˆŰŽ", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "«{name}» ŰšÙ‰Ù„Û•Ù† ŰŠŰ§Ű±Ű§Ú­Ù„Ű§Ű±ŰŻÙ‰ÙƒÙ‰ ŰȘÛŰ±Ù…Ù‰Ù†Ű§Ù„ Ù…Û•ŰźÙŸÙ‰ÙŠÛ•ŰȘلىك ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰ÙƒÙ‰Ù†Ù‰ ŰŻÛ•Ù„Ù‰Ù„Ù„Û•ŰŽ ŰŠÛˆÚ†ÛˆÙ†ŰŒ ŰŠÛ‡Ù„Ű§Ű±Ù†Ù‰Ú­ ŰŠÛˆŰłÙƒÛˆÙ†Ù‰ŰłÙ‰Ù†Ù‰Ú­ ŰŠÛˆŰłŰȘÙ‰ŰŻÙ‰ÙƒÙ‰ Ű±Û•Ù‚Û•Ù…Ù„Û•Ű±Ù†Ù‰ ŰłÛÙ„Ù‰ŰŽŰȘÛ‡Ű±Û‡ÙŸ ÙƒÛ†Ű±ÛˆÚ­. ŰŠÛ‡Ù„Ű§Ű±Ù…Û‡ ŰłÙ‰ŰČنىڭ QR ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČنى ŰłÙƒŰ§Ù†Ù†ÛŰ±Ù„Ù‰ÙŠŰ§Ù„Ű§ÙŠŰŻÛ‡.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ŰłÙ‰ŰČ ŰšÛ‡ ŰŠŰ§Ù„Ű§Ù‚Ù‰ŰŻŰ§ŰŽ ŰšÙ‰Ù„Û•Ù† ŰŠÛ‡Ú†Û‡Ű±Ù„Ù‰ŰŽÙ‰ÙŸ ŰšŰ§Ù‚Ù…Ù‰ŰșŰ§Ù†. ŰŠÛ‡Ù„Ű§Ű± ŰšÙ‰Ù„Û•Ù† ŰšÙˆÙ„ŰșŰ§Ù† ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰Ú­Ù‰ŰČ ŰŠÛ‡Ú†Û‡Ű±Ù„Ù‰ŰŽÙ‰ŰŽÙ†Ù‰ ŰšŰ§ŰŽÙ„Ù‰ŰșŰ§Ù†ŰŻÙ‰Ù† كېيىن ŰŠŰ§Ù†ŰŻÙ‰Ù† ÚŸŰ§ŰłÙ‰Ù„ ŰšÙˆÙ„Ù‰ŰŻÛ‡." }, @@ -1334,17 +1422,17 @@ "messageformat": "ŰŠÛ‡Ú†Û‡Ű±", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ŰŠÛ†Ú†ÛˆŰ±", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ŰŠÛ‡Ú†Û‡Ű± ŰŠÛ†Ú†ÛˆŰ±ÛˆŰŽ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ŰłÛ†ÚŸŰšÛ•ŰȘنى ŰŠÛ†Ú†ÛˆŰ±Û•Ù…ŰłÙ‰ŰČ۟", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰ ŰŠÛ†Ú†ÛˆŰ±Û•Ù…ŰłÙ‰ŰČ۟", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ŰšÛ‡ ÙŸŰ§Ű±Ű§Ú­ ŰšÛ‡ ŰŠÛˆŰłÙƒÛˆÙ†Ù‰ŰŻÙ‰Ù† ŰŠÛ†Ú†ÛˆŰ±ÛˆÙ„Ù‰ŰŻÛ‡.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ŰšÛ‡ ÙŸŰ§Ű±Ű§Ú­ŰŻÙ‰ÙƒÙ‰ ŰŠÛ‡Ú†Û‡Ű±Ù„Ű§Ű± ŰšÛ‡ ŰŠÛˆŰłÙƒÛˆÙ†Ù‰ŰŻÙ‰Ù† ŰŠÛ†Ú†ÛˆŰ±ÛˆÙ„Ù‰ŰŻÛ‡. ŰŠÛ‡Ú†Û‡Ű±Ù„Ű§Ű±Ù†Ù‰ ŰŠÛ†Ú†ÛˆŰ±ÚŻÛ•Ù†ŰŻÙ‰Ù† كېيىنمۇ ŰšÛ‡ ÙŸŰ§Ű±Ű§Ú­Ù†Ù‰ ÙŠÛ•Ù†Ù‰Ù„Ű§ ŰȘŰ§ÙŸŰ§Ù„Ű§ÙŠŰłÙ‰ŰČ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ÚŻÛ‡Ű±Û‡ÙŸÙŸÙ‰ŰŻÙ‰Ù† ŰŠŰ§ÙŠŰ±Ù‰Ù„Ù‰ŰŽ", @@ -1438,6 +1526,14 @@ "messageformat": "ÚŸÛ•Ű± ŰŠÙ‰ÙƒÙƒÙ‰ ÙŸŰ§Ű±Ű§Ú­ŰŻÙ‰ÙƒÙ‰ ŰŠÛ‡Ú†Û‡Ű±Ù„Ù‰ŰŽÙ‰ŰŽ ۟ۧŰȘÙ‰Ű±Ù‰Ú­Ù‰ŰČ ŰšÛ‡ ÙŠÛ•Ű±ŰŻÛ• ŰšÙ‰Ű±Ù„Û•ŰŽŰȘÛˆŰ±ÛˆÙ„ŰŻÙ‰.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} ÚŻÛ• ŰȘەۋە. ÚŸÛ•Ű± ŰŠÙ‰ÙƒÙƒÙ‰Ú­Ù„Ű§Ű± «{sharedGroup}» نىڭ ŰŠÛ•ŰČŰ§ŰłÙ‰.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} {conversationTitle} ÚŻÛ• ŰȘەۋە", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "نەقىل ŰŠÛÙ„Ù‰Ù†ŰșŰ§Ù† ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰Ú­ كىچىك Ű±Û•ŰłÙ‰Ù…Ù‰", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Ù‚Ű§ÙŠŰȘۧ Ú†Ű§Ù‚Ù‰Ű±", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰšŰ§ŰŽÙ„Ű§", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‚Ű§ قېŰȘىل", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ŰȘىكى ÙƒÙ‰ŰŽÙ‰Ù„Û•Ű± ŰšÛ•Ùƒ ÙƒÛ†ÙŸ ŰšÙˆÙ„ŰșŰ§Ú†Ù‚Ű§ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰŠÛˆÙ†ŰłÙ‰ŰČ Ù‚Ù‰Ù„Ù‰Ù†ŰŻÙ‰", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰŠÛ‡Ù‚ŰȘÛ‡Ű±Û‡ŰŽÙ„Ù‰Ű±Ù‰", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰȘÙˆŰŽŰȘى", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ÙƒŰ§Ù…ÛŰ±Ű§", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Ù‚ÙˆŰŽÛ‡Ù„Û‡ŰŽ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ŰšŰ§ŰŽÙ„Ű§ŰŽ", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰȘÙˆŰŽŰȘى", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ÙƒŰ§Ù…ÛŰ±Ű§ Ú†Û•ÙƒÙ„Û•Ù†ÚŻÛ•Ù†", @@ -1621,10 +1725,6 @@ "messageformat": "ÙƒŰ§Ù…ÛŰ±Ű§Ù†Ù‰ ŰŠÛÚ†Ù‰ŰŽ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ŰŠÛˆÙ†ŰłÙ‰ŰČ", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Ù…Ù‰ÙƒŰ±ÙˆÙÙˆÙ† Ú†Û•ÙƒÙ„Û•Ù†ÚŻÛ•Ù†", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ù…Ù‰ÙƒŰ±ÙˆÙÙˆÙ†Ù†Ù‰ ŰŠÛÚ†Ù‰ŰŽ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ÚŸÛ•Ù…ŰšÛ•ÚŸÙ‰Ű±Ù„Û•", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ŰŠÛÙƒŰ±Ű§Ù† ŰŠÙˆŰ±ŰȘŰ§Ù‚Ù„Ù‰ŰŽÙ‰ŰŽ Ú†Û•ÙƒÙ„Û•Ù†ÚŻÛ•Ù†", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ŰŠÛÙƒŰ±Ű§Ù† ŰŠÙˆŰ±ŰȘŰ§Ù‚Ù„Ù‰ŰŽÙ‰ŰŽÙ†Ù‰ ŰȘÙˆŰźŰȘىŰȘÙ‰ŰŽ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "قوڭŰșÛ‡Ű±Ű§Ù‚", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "قېŰȘىلŰșÛ‡Ú†Ù‰Ù„Ű§Ű±Ù†Ù‰ Ú†Ű§Ù‚Ù‰Ű±Ù‰ŰŽÙ‚Ű§ ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ ŰšÛ•Ùƒ چوڭ كېلىٟ Ù‚Ű§Ù„ŰŻÙ‰", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "قوڭŰșÛ‡Ű±Ű§Ù‚Ù†Ù‰ قوŰČŰșىŰȘÙ‰ŰŽ", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "قوڭŰșÛ‡Ű±Ű§Ù‚Ù†Ù‰ ŰŠÛŰȘÙ‰ŰŽ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "قوڭŰșÛ‡Ű±Ű§Ù‚Ù†Ù‰ ŰŠÛÚ†Ù‰ŰŽ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "ŰȘÛŰźÙ‰Ù…Û‡ ÙƒÛ†ÙŸ ŰȘŰ§Ù„Ù„Ű§ŰŽ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ŰłÙ‰ŰČ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ÙƒŰ§Ù…ÛŰ±Ű§ ŰȘŰ§Ù‚Ű§Ù‚", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰Ù†Ù‰ ÙƒÛ†Ű±ÛˆÚ­", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ŰŠÛ‡Ú†Û‡Ű±", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ŰšÙ‰ŰźÛ•ŰȘÛ•Ű±Ù„Ù‰Ùƒ Ù†ÙˆÙ…Û‡Ű±Ù‰Ù†Ù‰ ÙƒÛ†Ű±ÛˆÚ­", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ŰȘېلېفون Ù†ÙˆÙ…Û‡Ű±Ù‰Űșۧ ŰŠÛŰ±Ù‰ŰŽÛ•Ù„Ù…Ù‰ŰŻÙ‰. ŰȘÙˆŰ± ŰŠÛ‡Ù„Ù‰Ù†Ù‰ŰŽÙ‰Ú­Ù‰ŰČنى ŰȘÛ•ÙƒŰŽÛˆŰ±ÛˆÙŸ Ù‚Ű§ÙŠŰȘۧ ŰłÙ‰Ù†Ű§Ú­.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ŰšÛ‡ ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰ ÙŠÙˆÙ„Ù„Ű§ÙŸ ÙŸÛ•Ù‚Û•ŰȘ 3 ŰłŰ§ŰŠÛ•ŰȘ ŰŠÙ‰Ú†Ù‰ŰŻÙ‰Ù„Ű§ ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Û•ŰŽÙƒÛ• ŰšÙˆÙ„Ù‰ŰŻÛ‡.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ŰšÛ‡ ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰ ÙŠÙˆÙ„Ù„Ű§ÙŸ 24 ŰłŰ§ŰŠÛ•ŰȘ ŰŠÙ‰Ú†Ù‰ŰŻÙ‰Ù„Ű§ ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Û•ŰŽÙƒÛ• ŰšÙˆÙ„Ù‰ŰŻÛ‡.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ŰšÛ‡ ŰŠÛ‡Ú†Û‡Ű± ŰŠÛ†Ú†ÛˆŰ±ÛˆÙ„ÚŻÛ•Ù†", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Ù‚Ù‰ŰłŰȘÛ‡Ű±Ù…Ű§ ŰšÛ•Ùƒ چوڭ ŰšÙˆÙ„ŰșŰ§Ú†Ù‚Ű§ ÙƒÛ†Ű±ŰłÛ•ŰȘكىلى ŰšÙˆÙ„Ù…Ù‰ŰŻÙ‰.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "ŰšÛ•ŰČى Ù‚Ù‰ŰłŰȘÛ‡Ű±Ù…Ù‰Ù„Ű§Ű± ŰšÛ•Ùƒ چوڭ ŰšÙˆÙ„ŰșŰ§Ú†Ù‚Ű§ ÙƒÛ†Ű±ŰłÛ•ŰȘكىلى ŰšÙˆÙ„Ù…Ù‰ŰŻÙ‰.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ŰŠÙ‰ŰŠŰ§Ù†Û• ŰȘÛ•ÙŸŰłÙ‰Ù„Ű§ŰȘىŰșۧ ŰŠÛŰ±Ù‰ŰŽÛ•Ù„Ù…Ù‰ŰŻÙ‰", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Signal ŰłÙ‰Ù†Ű§Ù‚ Ù†Û•ŰŽŰ±Ù‰ ŰŠÛˆÚ†ÛˆÙ†Ù„Ű§", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ŰŠÛ‡Ú†Û‡Ű±Ù„Ű§Ű±Ù†Ù‰ ÙŸÛ•Ù‚Û•ŰȘ Signal ŰłÙ‰Ù†Ű§Ù‚ Ù†Û•ŰŽŰ±Ù‰ ŰŠÙ‰ŰŽÙ„Û•ŰȘÙƒÛˆÚ†Ù‰Ù„Ù‰Ű±Ù‰Ù„Ű§ ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Ù‰ÙŠÛ•Ù„Û•ÙŠŰŻÛ‡. ŰŠÛ•ÚŻÛ•Ű± ŰŠÛ‡Ú†Û‡Ű± ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Ù‰ŰłÙ‰Ú­Ù‰ŰČی ŰŠÛ‡Ù†Ù‰ ÙŸÛ•Ù‚Û•ŰȘ Signal ŰŠÛ•Ú­ يېڭى ŰłÙ‰Ù†Ű§Ù‚ Ù†Û•ŰŽŰ±Ù‰Ù†Ù‰ ŰŠÙ‰ŰŽÙ„Ù‰ŰȘÙ‰Û‹Ű§ŰȘÙ‚Ű§Ù† ÙƒÙ‰ŰŽÙ‰Ù„Û•Ű±Ù„Ű§ ÙƒÛ†Ű±Û•Ù„Û•ÙŠŰŻÛ‡.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ŰŠÛ‡Ú†Û‡Ű± ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Û•Ú­", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ŰŠÛ•ÚŻÛ•Ű± ŰłÙ‰ŰČ ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰ ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Ù‰ŰłÙ‰Ú­Ù‰ŰČی ŰŠÛ‡Ù†Ù‰ ÙŸÛ•Ù‚Û•ŰȘ Signalنىڭ ŰŠÛ•Ú­ يېڭى Ù†Û•ŰŽŰ±Ù‰Ù†Ù‰ ŰŠÙ‰ŰŽÙ„Ù‰ŰȘÙ‰Û‹Ű§ŰȘÙ‚Ű§Ù† ÙƒÙ‰ŰŽÙ‰Ù„Û•Ű±Ù„Ű§ ÙƒÛ†Ű±Û•Ù„Û•ÙŠŰŻÛ‡. ŰŠÛ‡Ù„Ű§Ű± ŰłÙ‰ŰČنىڭ ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰ ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Ù‰ÚŻÛ•Ù†Ù„Ù‰ÙƒÙ‰Ú­Ù‰ŰČنى ÙƒÛ†Ű±Û•Ù„Û•ÙŠŰŻÛ‡.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ÙƒÛ•Ù„ÚŻÛ•Ù† Û‹Ù‰ŰŻÛÙŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "ŰŠÛ‡Ű±Û‡Ù„ŰșŰ§Ù† ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "ŰŠÛ‡Ű±Û‡Ù„ŰșŰ§Ù† Û‹Ù‰ŰŻÛÙŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ŰłÙ‰ŰČنى Ú†Ű§Ù‚Ù‰Ű±Ù‰Û‹Ű§ŰȘÙ‰ŰŻÛ‡", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Ù‚Ű§ÙŠŰȘۧ ŰŠÛ‡Ù„Ù‰Ù†Ù‰Û‹Ű§ŰȘÙ‰ŰŻÛ‡...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} ÙƒÙ‰ŰŽÙ‰}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ŰŠŰ§ŰźÙ‰Ű±Ù„Ű§ŰŽŰȘÛ‡Ű±Û‡ŰŽ", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ŰŠŰ§ÙŠŰ±Ù‰Ù„Ù‰ŰŽ", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Ù…Ù‰ÙƒŰ±ÙˆÙÙˆÙ† ŰŠÛŰȘىك", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Ù…Ù‰ÙƒŰ±ÙˆÙÙˆÙ† ŰŠÙˆÚ†Û‡Ù‚", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "قوڭŰșÛ‡Ű±Ű§Ù‚ ŰŠÙˆÚ†Û‡Ù‚", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "قوڭŰșÛ‡Ű±Ű§Ù‚ ŰŠÛŰȘىك", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ŰȘÛ•Ú­ŰŽÛ•ÙƒÙ„Û•Ű±", @@ -3468,13 +3668,25 @@ "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù†Ù‰ ÙŸÛˆŰȘۈن ŰŠÛÙƒŰ±Ű§Ù†Ù„Ű§ŰŽŰȘÛ‡Ű±Û‡ŰŽ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ÙƒŰ§ŰȘەكچە ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽÙ‰ÚŻÛ• ŰŠŰ§Ù„Ù…Ű§ŰŽŰȘÛ‡Ű±Û‡ŰŽ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽÙ†Ù‰ ŰŠÛ†ŰČÚŻÛ•Ű±ŰȘÙ‰ŰŽ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ÙŠŰ§Ú­Ű±Ű§ŰȘقۇ ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽÙ‰ÚŻÛ• ŰŠŰ§Ù…Ű§ŰŽŰȘÛ‡Ű±Û‡ŰŽ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ŰłÛŰȘÙƒŰ§ ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ÙŠŰ§Ù†ŰšŰ§Ù„ŰŻŰ§Ù‚ ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ŰłÛ†ŰČÙ„Ù‰ÚŻÛˆÚ†Ù‰ ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽÙ‰", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽ ÙŠÛÚ­Ù‰Ù„Ű§Ù†ŰŻÙ‰", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ŰȘىن ŰŠŰ§ÙŠŰ±Ù‰Ù„", @@ -3576,6 +3788,14 @@ "messageformat": "ŰŹÛ•ŰČملە", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ŰŠÛ‡Ú†Û‡Ű±Ù†Ù‰ ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Ù‰ÙŠÛ•Ù„Ù…Ù‰ŰŻÙ‰", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ŰšÛ‡ ŰŠÛ‡Ú†Û‡Ű±Űșۧ ÙŸÛ•Ù‚Û•ŰȘ {max,number} ŰȘÛ•ÚŸŰ±Ù‰Ű±Ù„Û•ŰŽÙ†Ù‰ Ù‚ÙˆÙ„Ù„Ű§Ù†Űșىلى ŰšÙˆÙ„Ù‰ŰŻÛ‡.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ÙƒÛ•Ú†ÛˆŰ±ÛˆÚ­ŰŒ ŰšÛ‡ sgnl:// ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰ŰłÙ‰ ۟ۧŰȘۧ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى ŰŠÙ‰ŰłÙ…Ù‰", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ŰłÙ‰ŰČنىڭ ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈى Ù†Ű§Ù…Ù‰Ú­Ù‰ŰČۯۧ ŰšÛ•ŰČى Ù…Û•ŰłÙ‰Ù„Ù‰Ù„Û•Ű± ŰšŰ§Ű±ŰŒ ŰšÛ‡ ŰŠÛ•Ù…ŰŻÙ‰ ŰłÙ‰ŰČنىڭ ÚŸÛŰłŰ§ŰšÙ‰Ú­Ù‰ŰČŰșۧ ŰȘÛ•Ù‚ŰłÙ‰Ù… Ù‚Ù‰Ù„Ù‰Ù†Ù…Ű§ÙŠŰŻÛ‡.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ù†Ù‰ ŰŠÛ†Ú†ÛˆŰ±ÛˆŰŽ", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰ ŰšÛÙƒÙ‰ŰȘÙ‰ŰŽ", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR ÙƒÙˆŰŻÙ‰ ÙŠŰ§ÙƒÙ‰ ŰŠÛ‡Ù„Ű§Ù†Ù…Ű§", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ù†Ù‰ Ù‚Ű§ÙŠŰȘۧ ŰšÛÙƒÙ‰ŰȘÙ‰ŰŽ ÙƒÛŰ±Û•Ùƒ", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰ ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰ŰłÙ‰Ù†Ù‰ Ù‚Ű§ÙŠŰȘۧ ŰšÛÙƒÙ‰ŰȘÙ‰ŰŽ ÙƒÛŰ±Û•Ùƒ", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ŰŠÛ•ŰČŰ§Ù„Ù‰Ù‚ ŰŠÙ‰ŰłÙ…Ù‰Ú­Ù‰ŰČنى ÙŸŰ§ÙŠÙ„Ù‰ŰŽÙ‰Ú­", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ù†Ù‰ ŰŠÛ†Ú†ÛˆŰ±ÛˆŰŽ", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ŰšÛ‡Ù†ŰŻŰ§Ù‚ قىلŰșŰ§Ù†ŰŻŰ§ ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰ ŰŠÛ†Ú†ÛˆŰ±ÛˆÙ„Ù‰ŰŻÛ‡ ۋە ŰšŰ§ŰŽÙ‚Ù‰Ù„Ű§Ű± ŰšÛ‡ ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ù†Ù‰ ŰŠÙ‰ŰŽÙ„Û•ŰȘŰłÛ• ŰšÙˆÙ„Ù‰ŰŻÛ‡. ŰŹÛ•ŰČÙ…Ù„Û•ŰŽŰȘÛˆŰ±Û•Ù…ŰłÙ‰ŰČ۟", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ŰšÛ‡ ŰłÙ‰ŰČنىڭ ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ú­Ù‰ŰČنى ŰŠÛ†Ú†ÛˆŰ±Ù‰Û‹ÛŰȘÙ‰ŰŻÛ‡ ÚŸÛ•Ù…ŰŻÛ• QR ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČ Û‹Û• ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰ŰłÙ‰ ŰšÛÙƒŰ§Ű± Ù‚Ù‰Ù„Ù‰Ù†Ù‰ŰŻÛ‡. \"{username}\" ŰšÙˆÙ„ŰłŰ§ ŰšŰ§ŰŽÙ‚Ù‰Ù„Ű§Ű±Ù†Ù‰Ú­ ŰŠÙ‰ŰŽÙ„Ù‰ŰȘÙ‰ŰŽÙ‰ÚŻÛ• ŰłÛ‡Ù†Û‡Ù„Ù‰ŰŻÛ‡. ŰŹÛ•ŰČÙ‰Ù…Ù„Û•ŰŽŰȘÛˆŰ±Û•Ù…ŰłÙ‰ŰČ۟", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ÚŸÛÙƒŰ§ÙŠÙ‰Ù„Û•Ű±Ù†Ù‰ ŰŠÛ•Ù…ŰŻÙ‰ ŰŠÙˆŰ±ŰȘŰ§Ù‚Ù„Ù‰ŰŽŰ§Ù„Ù…Ű§ÙŠŰłÙ‰ŰČ ÙŠŰ§ÙƒÙ‰ ÙƒÛ†Ű±Û•Ù„Ù…Û•ÙŠŰłÙ‰ŰČ. ŰłÙ‰ŰČ ÙŠÛÙ‚Ù‰Ù†ŰŻŰ§ ŰŠÙˆŰ±ŰȘŰ§Ù‚Ù„Ű§ŰŽÙ‚Ű§Ù† ÚŸÛÙƒŰ§ÙŠÛ• ÙŠÛÚ­Ù‰Ù„Ű§Ù†Ù…Ù‰Ù„Ù‰Ű±Ù‰Ù…Û‡ ŰŠÛ†Ú†ÛˆŰ±ÛˆÙ„Ù‰ŰŻÛ‡.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ŰȘىل", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ŰȘىل", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ŰłÙ‰ŰłŰȘÛÙ…Ű§ ŰȘىلى", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ŰȘىل ŰŠÙ‰ŰČŰŻÛ•ŰŽ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "{searchTerm} ŰŠÛˆÚ†ÛˆÙ† نەŰȘÙ‰ŰŹÛ• يوق", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ŰšÛÙƒÙ‰ŰȘÙ‰ŰŽ", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Ù‚ÙˆÙ„Ù„Ù‰Ù†Ù‰ŰŽ ŰŠÛˆÚ†ÛˆÙ† Signal نى Ù‚Ű§ÙŠŰȘۧ قوŰČŰșىŰȘىڭ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ŰȘىلنى ŰŠÛ†ŰČÚŻÛ•Ű±ŰȘÙ‰ŰŽ ŰŠÛˆÚ†ÛˆÙ† ŰŠÛ•ÙŸÙ†Ù‰ Ù‚Ű§ÙŠŰȘۧ قوŰČŰșىŰȘÙ‰ŰŽ ÙƒÛŰ±Û•Ùƒ.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ù‚Ű§ÙŠŰȘۧ قوŰČŰșىŰȘÙ‰ŰŽ", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} Ù†Û•ŰŽŰ±Ù‰Ù†Ù‰ ÙŠÛÚ­Ù‰Ù„Ű§ŰŽÙ‚Ű§ ŰšÙˆÙ„Ù‰ŰŻÛ‡", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ŰȘÛ•Ú­ŰŽÛ•ÙƒÙ„Ù‰Ű±Ù‰Ú­Ù‰ŰČنى ŰłŰ§Ù‚Ù„Ù‰ŰșŰ§Ù†ŰŻŰ§ ۟ۧŰȘŰ§Ù„Ù‰Ù‚ ÙƒÛ†Ű±ÛˆÙ„ŰŻÙ‰. Ù‚Ű§ÙŠŰȘۧ ŰłÙ‰Ù†Ű§Ú­.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ŰŠÛ‡Ú†Û‡Ű±", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ŰȘÛŰźÙ‰Ù…Û‡ ÙƒÛ†ÙŸ ŰŠÛ‡ŰłÙ„Û‡Űš", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ŰŠÛ•ŰłÙ„Ù‰ÚŻÛ• Ù‚Ű§ÙŠŰȘÛ‡Ű±", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ŰšÙˆÙ„ŰŻÙ‰", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ù†Ù‰Ú­ ŰŠÛ‡Ù„Ű§Ù†Ù…Ű§ Ű±Û•Ú­ÚŻÙ‰ŰŒ {total,number}نىڭ{index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ŰŠÛ•ÚŻÛ•Ű± ŰłÙ‰ŰČ QR ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČنى ÙŠÛÚ­Ù„Ù‰ŰłÙ‰Ú­Ù‰ŰČی ŰłÙ‰ŰČنىڭ ÚŸŰ§ŰČÙ‰Ű±Ù‚Ù‰ QR ÙƒÙˆŰŻÙ‰Ú­Ù‰ŰČ Û‹Û• ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰Ú­Ù‰ŰČ ŰŠÙ‰ŰŽÙ„Ù‰Ù…Û•ÙŠŰŻÛ‡.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰Ù†Ù‰ ÙŠÛÚ­Ù‰Ù„Ű§Û‹Ű§ŰȘÙ‰ŰŻÛ‡...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR ÙƒÙˆŰŻÙ‰ ۋە ŰŠÛ‡Ù„Ű§Ù†Ù…Ù‰ŰłÙ‰ ŰšÛÙƒÙ‰ŰȘÙ‰Ù„Ù…Ù‰ŰŻÙ‰. ŰȘÙˆŰ± ŰŠÛ‡Ù„Ù‰Ù†Ù‰ŰŽÙ‰Ù†Ù‰ ŰȘÛ•ÙƒŰŽÛˆŰ±ÛˆÙŸ Ù‚Ű§ÙŠŰȘۧ ŰłÙ‰Ù†Ű§Ú­.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Signal ŰŠÙ‰ŰŽÙ„Û•ŰȘكۈچى Ù†Ű§Ù…Ù‰Ù†Ù‰ ŰšÛ•Ù„ÚŻÙ‰Ù„Û•Ú­", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "Ù‚Ű§ÙŠŰȘۧ ÙŠÙˆÙ„Ù„Ű§", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ŰȘÛŰźÙ‰Ù…Û‡ ÙƒÛ†ÙŸ Ù…Û•ŰŽŰșÛ‡Ù„Ű§ŰȘ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰ŰŽÙ„Ű§Ű±", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "يېڭى Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "يېڭى Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ŰȘÛŰźÙ‰Ù…Û‡ ÙƒÛ†ÙŸ Ù…Û•ŰŽŰșÛ‡Ù„Ű§ŰȘ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰȘŰ§Ű±Ù‰ŰźÙ‰Ù†Ù‰ ŰȘۧŰČÙ‰Ù„Ű§ŰŽ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰȘŰ§Ű±Ù‰ŰźÙ‰Ù†Ù‰ ŰȘۧŰČÙ‰Ù„Ű§Ù…ŰłÙ‰ŰČ۟", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ŰšÛ‡ Ù…Û•ŰŽŰșÛ‡Ù„Ű§ŰȘ ŰšŰ§Ű±Ù„Ù‰Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰȘŰ§Ű±Ù‰ŰźÙ‰Ù†Ù‰ Ù…Û•Ú­ÚŻÛˆÙ„ÛˆÙƒ ŰŠâ€Û†Ú†ÛˆŰ±Ù‰ŰŻÛ‡", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ŰȘۧŰČÙ‰Ù„Ű§", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ۟ۧŰȘÙ‰Ű±Ù‰ŰłÙ‰ ŰȘۧŰČÙ‰Ù„Ű§Ù†ŰŻÙ‰", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ÙƒÛ†Ű±ÛˆŰŽ ÙŠŰ§ÙƒÙ‰ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰšŰ§ŰŽÙ„Ù‰ŰȘÙ‰ŰŽ ŰŠÛˆÚ†ÛˆÙ† ŰšÛ‡ ÙŠÛ•Ű±Ù†Ù‰ چېكىڭ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ŰŠÙ‰ŰČŰŻÛ•", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ÙŠÙˆÙ‚Ű§Ù„ŰșŰ§Ù†Ù„Ű§Ű± ŰšÙ‰Ù„Û•Ù† ŰłÛˆŰČÛˆŰŽ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ŰŠŰ§Ù„Ù…Ű§ŰŽŰȘÛ‡Ű±", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "يېڭى ŰšÙ‰Ű± Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ يوق. ŰŻÙˆŰłŰȘىڭىŰČŰșۧ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ قىلىٟ ŰšŰ§ŰŽÙ„Ű§Ú­.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "{query} ŰŠÛˆÚ†ÛˆÙ† نەŰȘÙ‰ŰŹÛ• يوق", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ÙƒÛÙ„Ù‰Û‹Ű§ŰȘÙ‚Ű§Ù†", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ŰŠÛ‡Ű±Û‡Ù„Űșىنى", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ŰŠÛÙ„Ù‰Ù†Ù…Ù‰Űșىنى", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "يېڭى ŰšÙ‰Ű± ÙŸŰ§Ű±Ű§Ú­ يوق.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "{query} ŰŠÛˆÚ†ÛˆÙ† نەŰȘÙ‰ŰŹÛ• يوق", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {ŰŠÛ‡Ű±Û‡Ù„ŰșŰ§Ù† ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} other {ÙƒÛ•Ù„ÚŻÛ•Ù† ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚}}} Video {{direction, select, Outgoing {ŰŠÛ‡Ű±Û‡Ù„ŰșŰ§Ù† Û‹Ù‰ŰŻÛÙŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} other {ÙƒÛ•Ù„ÚŻÛ•Ù† Û‹Ù‰ŰŻÛÙŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚}}} Group {{direction, select, Outgoing {ŰŠÛ‡Ű±Û‡Ù„ŰșŰ§Ù† ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰} other {ÙƒÛ•Ù„ÚŻÛ•Ù† ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰}}} other {{direction, select, Outgoing {قىلىنŰșŰ§Ù† Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} other {ÙƒÛ•Ù„ÚŻÛ•Ù† Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ŰŠÛÙ„Ù‰Ù†Ù…Ù‰ŰșŰ§Ù† ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} Video {ŰłÛ†ŰČÙ„Û•ŰŽÙ…Ù‰ÚŻÛ•Ù† ŰłÙ‰Ù† Ú†Ű§Ù‚Ù‰Ű±Ù‰ŰŽ} Group {ŰŠÛÙ„Ù‰Ù†Ù…Ù‰ŰșŰ§Ù† ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰} other {ŰłÛ†ŰČÙ„Û•ŰŽÙ…Ù‰ÚŻÛ•Ù† Ú†Ű§Ù‚Ù‰Ű±Ù‰ŰŽ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ŰŹŰ§Û‹Ű§ŰšŰłÙ‰ŰČ ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} Video {ŰŹŰ§Û‹Ű§ŰšŰłÙ‰ŰČ Û‹Ù‰ŰŻÛÙŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} Group {ŰŹŰ§Û‹Ű§ÙŸŰłÙ‰ŰČ ŰȘوٟ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰} other {ŰŹŰ§Û‹Ű§ÙŸŰłÙ‰ŰČ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Ű±Û•ŰȘ قىلىنŰșŰ§Ù† ŰŠŰ§Û‹Ű§ŰČلىق Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} Video {Ű±Û•ŰȘ قىلىنŰșŰ§Ù† Û‹Ù‰ŰŻÛÙŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚} Group {Ű±Û•ŰȘ قىلىنŰșŰ§Ù† ŰȘوٟ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰} other {Ű±Û•ŰȘ قىلىنŰșŰ§Ù† Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number} ŰšŰ§ŰŽÙ‚Ù‰Ù„Ű§Ű± يېŰČÙ‰Û‹Ű§ŰȘÙ‰ŰŻÛ‡.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "ÙŠÛÚ­Ù‰Ù„Ù‰Ù‚Ù„Ű§Ű±", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "كىچىك ŰŠÛ†ŰČÚŻÛ•Ű±ŰȘÙ‰ŰŽÙ„Û•Ű± ÙƒÙ‰Ű±ÚŻÛˆŰČÛˆÙ„ŰŻÙ‰ŰŒ ÙƒŰ§ŰŽÙ‰Ù„Ű§ ÚŸÛ•Ù„ Ù‚Ù‰Ù„Ù‰Ù†ŰŻÙ‰ ۋە ŰŠÙ‰Ù‚ŰȘÙ‰ŰŻŰ§Ű± ŰŠÛ•Ù„Ű§Ù„Ű§ŰŽŰȘÛ‡Ű±Û‡Ù„ŰŻÙ‰. Signal نى ŰŠÙ‰ŰŽÙ„Û•ŰȘكەنلىكىڭىŰČÚŻÛ• Ű±Û•ÚŸÙ…Û•ŰȘ!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ŰšÛ‡ ÙŠÛÚ­Ù‰Ù„Ű§ŰŽ ŰŠŰ§Û‹Ű§ŰČلىق ۋە Û‹Ù‰ŰŻÛŰŠÙˆÙ„Û‡Ù‚ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù„Ű§Ű±ŰŻÙ‰ÙƒÙ‰ ۋە ŰšÛ•ŰČى كىچىك ÚŸÛ†ŰŹŰŹÛ•ŰȘ ÙŠÛÚ­Ù‰Ù„Ù‰Ù†Ù‰ŰŽÙ„Ù‰Ű±Ù‰ŰŻÙ‰ÙƒÙ‰ ÙŠŰ§ŰźŰŽÙ‰Ù„Ù‰Ù†Ù‰ŰŽÙ„Ű§Ű±Ù†Ù‰ ŰŠÛ†ŰČ ŰŠÙ‰Ú†Ù‰ÚŻÛ• ŰŠŰ§Ù„Ù‰ŰŻÛ‡. (Ű±Û•ÚŸÙ…Û•ŰȘی {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "ŰŠÛ•Ù…ŰŻÙ‰ Signal ۯۧ ŰȘÛ†Û‹Û•Ù†ŰŻÙ‰ÙƒÙ‰ ŰŠÛ‡ŰłÛ‡Ù„ ŰšÙ‰Ù„Û•Ù† ŰłÙ‰ŰłŰȘÛÙ…Ű§ ŰȘىلىنى ŰŠÛ†ŰČÚŻÛ•Ű±ŰȘمەي ŰȘÛ‡Ű±Û‡ÙŸÙ…Û‡ ŰȘŰ§Ù„Ù„Ù‰ŰșŰ§Ù† ŰȘىلىڭىŰČنى ŰŠÛ†ŰČÚŻÛ•Ű±ŰȘÛ•Ù„Û•ÙŠŰłÙ‰ŰČ (Signal ŰȘÛ•Ú­ŰŽÛ•Ùƒ > ÙƒÛ†Ű±ÛˆÙ†ÛˆŰŽ > ŰȘىل)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ŰšÙ‰ŰČ ŰšÛ•ŰČى ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ ŰŠÛ‡Ù‚ŰȘÛ‡Ű±Û‡ŰŽ ŰłÙ‰Ù†ŰšÛ•Ù„ÚŻÙ‰Ù„Ù‰Ű±Ù‰Ù†Ù‰ ÙŠÛÚ­Ù‰Ù„Ű§ÙŸ چىقŰȘۇق." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚ ŰČŰ§Ù„Ù‰Űșۧ Ù‚ÙˆŰŽÛ‡Ù„ŰșŰ§Ù†ŰŻŰ§ macOS ŰŠÛˆŰłÙƒÛˆÙ†Ù‰Ù„Û•Ű±ŰŻÛ• ŰšÛ•ŰČى Û‹Ű§Ù‚Ù‰ŰȘÙ„Ű§Ű±ŰŻŰ§ ÙƒÛ†Ű±ÛˆÙ„Ù‰ŰŻÙ‰ŰșŰ§Ù† ÙƒÛÚ†Ù‰ÙƒÙ‰ŰŽ Ù…Û•ŰłÙ‰Ù„Ù‰ŰłÙ‰Ù†Ù‰ ÚŸÛ•Ù„ Ù‚Ù‰Ù„ŰŻÛ‡Ù‚." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ŰšÙ‰Ű±Û•ÙŠÙ„Û•Ù† ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ Ú†Ű§Ù‚Ù‰Ű±Ù‰Ù‚Ù‰Űșۧ Ù‚ÙˆŰŽÛ‡Ù„ŰșŰ§Ù† ÙŠŰ§ÙƒÙ‰ ŰŠÛ‡Ù†Ù‰Ú­ŰŻÙ‰Ù† ŰŠŰ§ÙŠŰ±Ù‰Ù„ŰșŰ§Ù†ŰŻÙ‰ÙƒÙ‰ Û‹Ù‰ŰŻÛÙŠÙˆ ŰŠÛ†ŰȘكۈنچى ÙƒŰ§Ű±ŰȘون Ù…Û•ŰłÙ„Ù‰ŰłÙ‰Ù†Ù‰ ÚŸÛ•Ù„ Ù‚Ù‰Ù„ŰŻÛ‡Ù‚." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ÚŸŰ§ŰČÙ‰Ű± ÙŸŰ§Ű±Ű§Ú­Ù„Ù‰ŰŽÙ‰ŰŽ ŰłÛ•Ű±Ù„Û•Û‹ÚŸÛ•ŰłÙ‰ŰŻÙ‰ÙƒÙ‰ ŰŠŰ§Ű±ŰźÙ‰ÙŸ Ű±Û•ŰłÙ‰Ù…Ù‰ ÙŠŰ§ÙƒÙ‰ ÚŻÛ‡Ű±Û‡ÙŸÙŸŰ§ ۚۧێ ŰłÛˆŰ±Ù‰ŰȘىنى Ú†ÛÙƒÙ‰ÙŸŰŒ ÙŸŰ§Ű±Ű§Ú­ ŰȘÛ•Ú­ŰŽÛ•ÙƒÙ„Ù‰Ű±Ù‰ÚŻÛ• ÙƒÙ‰Ű±Û•Ù„Û•ÙŠŰłÙ‰ŰČ ÙŠŰ§ÙƒÙ‰ ŰšÛ‡ ÙŸŰ§Ű±Ű§Ú­ŰŻÙ‰ÙƒÙ‰ ÙƒÛ†Ű±Ù…Û•ÙŠ Ù‚Ű§Ù„ŰșŰ§Ù† ÚŸÛÙƒŰ§ÙŠÙ‰Ù„Û•Ű±Ù†Ù‰ ÙƒÛ†Ű±Û•Ù„Û•ÙŠŰłÙ‰ŰČ. Ű±Û•ÚŸÙ…Û•ŰȘی {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/uk-UA/messages.json b/_locales/uk-UA/messages.json index 9c5323da2e..094445dc6a 100644 --- a/_locales/uk-UA/messages.json +++ b/_locales/uk-UA/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ĐŸĐŸĐŒĐžĐ»Đșа базО ĐŽĐ°ĐœĐžŃ…", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Із Đ±Đ°Đ·ĐŸŃŽ ĐŽĐ°ĐœĐžŃ… ŃŃ‚Đ°Đ»Đ°ŃŃ ĐżĐŸĐŒĐžĐ»Đșа. Во ĐŒĐŸĐ¶Đ”Ń‚Đ” сĐșĐŸĐżŃ–ŃŽĐČато ĐżĐŸĐŒĐžĐ»Đșу і Đ·ĐČ'ŃĐ·Đ°Ń‚ĐžŃŃ Đ·Ń– ŃĐ»ŃƒĐ¶Đ±ĐŸŃŽ ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒĐșĐž Signal, Ń‰ĐŸĐ± ĐŽĐŸĐżĐŸĐŒĐŸĐłŃ‚Đž ĐœĐ°ĐŒ ĐČорішото цю ĐżŃ€ĐŸĐ±Đ»Đ”ĐŒŃƒ. ĐŻĐșŃ‰ĐŸ ĐČĐ°ĐŒ ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ ĐČĐžĐșĐŸŃ€ĐžŃŃ‚Đ°Ń‚Đž Signal ĐżŃ€ĐŸŃŃ‚ĐŸ зараз, ŃĐżŃ€ĐŸĐ±ŃƒĐčтД ĐČОЎалОтО сĐČĐŸŃ— ĐŽĐ°ĐœŃ– та ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚Đž ĐżŃ€ĐŸĐłŃ€Đ°ĐŒŃƒ.\n\nЗĐČĐ”Ń€ĐœŃƒŃ‚ĐžŃŃ ĐŽĐŸ службО ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒĐșĐž ĐŒĐŸĐ¶ĐœĐ° тут: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ВОЎалОтО усі ĐŽĐ°ĐœŃ– та ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚Đž", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ВОЎалОтО ĐŽĐ°ĐœŃ– і ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚Đž", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ВОЎалОтО ĐČсі ĐŽĐ°ĐœŃ– ĐœĐ°Đ·Đ°ĐČжЎО?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Усю Ń–ŃŃ‚ĐŸŃ€Ń–ŃŽ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœŃŒ і ĐŒĐ”ĐŽŃ–Đ°Ń„Đ°ĐčлО буЎД ĐœĐ°Đ·Đ°ĐČжЎО ĐČĐžĐŽĐ°Đ»Đ”ĐœĐŸ Đ· Ń†ŃŒĐŸĐłĐŸ ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃŽ. Во Đ·ĐŒĐŸĐ¶Đ”Ń‚Đ” ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато Signal ĐœĐ° Ń†ŃŒĐŸĐŒŃƒ ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃ— ĐżŃ–ŃĐ»Ń Ń‚ĐŸĐłĐŸ, яĐș Đ·ĐœĐŸĐČу ĐčĐŸĐłĐŸ проĐČ'ŃĐ¶Đ”Ń‚Đ”. Щя Юія ĐœĐ” ĐČĐžĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐŽĐ°ĐœŃ– Đ· ĐČĐ°ŃˆĐŸĐłĐŸ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ°.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "Đ’Đ”Ń€ŃŃ–Ń ĐČĐ°ŃˆĐŸŃ— базО ĐŽĐ°ĐœĐžŃ… ĐœĐ” ĐČŃ–ĐŽĐżĐŸĐČіЮає ціĐč ĐČДрсії Signal. ĐŸĐ”Ń€Đ”ĐșĐŸĐœĐ°ĐčŃ‚Đ”ŃŃ, Ń‰ĐŸ ĐČіЮĐșроĐČаєтД ĐœĐ° ĐșĐŸĐŒĐż'ютДрі ĐŸŃŃ‚Đ°ĐœĐœŃŽ ĐČДрсію Signal.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&ЀаĐčĐ»", @@ -300,6 +316,70 @@ "messageformat": "Чато", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "Із ĐČĐ°ŃˆĐžĐŒ Ń–ĐŒĐ”ĐœĐ”ĐŒ ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача ŃŃ‚Đ°Đ»Đ°ŃŃ ĐżĐŸĐŒĐžĐ»Đșа. Đ’ĐŸĐœĐŸ Đ±Ń–Đ»ŃŒŃˆĐ” ĐœĐ” ĐœĐ°Đ»Đ”Đ¶ĐžŃ‚ŃŒ ĐŽĐŸ ĐČĐ°ŃˆĐŸĐłĐŸ аĐșĐ°ŃƒĐœŃ‚Ńƒ. Во ĐŒĐŸĐ¶Đ”Ń‚Đ” ŃĐżŃ€ĐŸĐ±ŃƒĐČато ĐČŃŃ‚Đ°ĐœĐŸĐČото цД Ń–ĐŒ'я ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ Đ°Đ±ĐŸ ĐČОбратО ĐœĐŸĐČĐ”.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ВопраĐČото", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "Із ĐČĐ°ŃˆĐžĐŒ QR-ĐșĐŸĐŽĐŸĐŒ і ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃĐŒ Ń–ĐŒĐ”ĐœŃ– ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача ŃŃ‚Đ°Đ»Đ°ŃŃ ĐżĐŸĐŒĐžĐ»Đșа. Đ’ĐŸĐœĐž Đ±Ń–Đ»ŃŒŃˆĐ” ĐœĐ” ЮіĐčŃĐœŃ–. СтĐČĐŸŃ€Ń–Ń‚ŃŒ ĐœĐŸĐČĐ” ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ ĐŽĐ»Ń Ń‚ĐŸĐłĐŸ, Ń‰ĐŸĐ± ĐżĐŸĐŽŃ–Đ»ĐžŃ‚ĐžŃŃ ĐœĐžĐŒ Đ· Ń–ĐœŃˆĐžĐŒĐž.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ВопраĐČото", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ĐŸĐŸĐșазатО ĐČĐșлаЎĐșĐž", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ĐŸŃ€ĐžŃ…ĐŸĐČато ĐČĐșлаЎĐșĐž", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ĐĄŃ‚Đ°Đ»Đ°ŃŃ ĐżĐŸĐŒĐžĐ»Đșа", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "ĐĐ” ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐŸ {count,number}", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ĐŸĐŸĐ·ĐœĐ°Ń‡Đ”ĐœĐŸ яĐș ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐ”", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "Чато", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "ВоĐșлОĐșĐž", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ĐĄŃ‚ĐŸŃ€Ń–Đ·", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ĐĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "ĐžĐœĐŸĐČото Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ĐŸŃ€ĐŸŃ„Ń–Đ»ŃŒ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ĐĐ°Đ·Đ°ĐŽ", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "Щі чато Đ±ŃƒĐ»ĐŸ заархіĐČĐŸĐČĐ°ĐœĐŸ. Во ĐżĐŸĐ±Đ°Ń‡ĐžŃ‚Đ” їх у ĐČŃ…Ń–ĐŽĐœĐžŃ…, лОшД ĐșĐŸĐ»Đž ĐČ ĐœĐžŃ… Đ·'яĐČĐ»ŃŃ‚ŃŒŃŃ ĐœĐŸĐČі ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "УсД ĐŸĐŽĐœĐŸ Đ·Đ°Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃƒĐČато", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "УсД ĐŸĐŽĐœĐŸ ĐżŃ€ĐžŃ”ĐŽĐœĐ°Ń‚ĐžŃŃ", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ĐŸŃ€ĐŸĐŽĐŸĐČжОтО ĐŽĐ·ĐČŃ–ĐœĐŸĐș", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ĐšĐŸĐŽĐž бДзпДĐșĐž ĐŸĐœĐŸĐČĐ»ŃŽŃŽŃ‚ŃŒŃŃ.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "Đ”Ń–Đ·ĐœĐ°Ń‚ĐžŃŃŒ Đ±Ń–Đ»ŃŒŃˆĐ”", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ĐŸĐŸĐżĐ”Ń€Đ”ĐŽĐœŃ–Đč ĐșĐŸĐŽ бДзпДĐșĐž", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "ĐĐ°ŃŃ‚ŃƒĐżĐœĐžĐč ĐșĐŸĐŽ бДзпДĐșĐž", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Đ’Đ”Ń€ŃŃ–Ń ĐșĐŸĐŽŃƒ бДзпДĐșĐž, {index,number} Đ· {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Đ’Ń–ĐŽĐŒŃ–Ń‚ĐžŃ‚Đž яĐș пДрДĐČŃ–Ń€Đ”ĐœĐžĐč", @@ -663,33 +747,41 @@ "messageformat": "ЧітĐșа ĐČДрОфіĐșація", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Đ©ĐŸĐ± пДрДĐČірото ĐœĐ°ŃĐČĐœŃ–ŃŃ‚ŃŒ ĐœĐ°ŃĐșŃ€Ń–Đ·ĐœĐŸĐłĐŸ шофруĐČĐ°ĐœĐœŃ Đ· ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ”ĐŒ {name}, ĐżĐŸŃ€Ń–ĐČĐœŃĐčтД ĐœĐ°ĐČĐ”ĐŽĐ”ĐœŃ– ĐČОщД цофро Ń–Đ· Ń†ĐžŃ„Ń€Đ°ĐŒĐž ĐœĐ° ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃ— ĐČĐ°ŃˆĐŸĐłĐŸ спіĐČŃ€ĐŸĐ·ĐŒĐŸĐČĐœĐžĐșа. ĐšĐŸŃ€ĐžŃŃ‚ŃƒĐČач таĐșĐŸĐ¶ ĐŒĐŸĐ¶Đ” ĐČіЮсĐșĐ°ĐœŃƒĐČато ĐČаш ĐșĐŸĐŽ за ĐŽĐŸĐżĐŸĐŒĐŸĐłĐŸŃŽ сĐČĐŸĐłĐŸ ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃŽ.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "Đ”Ń–Đ·ĐœĐ°Ń‚ĐžŃŃŒ Đ±Ń–Đ»ŃŒŃˆĐ”", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Đ©ĐŸĐ± пДрДĐČірото ĐœĐ°ŃĐČĐœŃ–ŃŃ‚ŃŒ ĐœĐ°ŃĐșŃ€Ń–Đ·ĐœĐŸĐłĐŸ шофруĐČĐ°ĐœĐœŃ Đ· ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ”ĐŒ {name}, ĐżĐŸŃ€Ń–ĐČĐœŃĐčтД ĐșĐŸĐ»ŃŒĐŸŃ€ĐŸĐČу ĐșартĐșу ĐČОщД Đ· ĐșартĐșĐŸŃŽ ĐœĐ° ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃ— ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача і пДрДĐČіртД, чо Đ·Đ±Ń–ĐłĐ°ŃŽŃ‚ŃŒŃŃ цофро. ĐŻĐșŃ‰ĐŸ цофро ĐœĐ” Đ·Đ±Ń–ĐłĐ°ŃŽŃ‚ŃŒŃŃ, ŃĐżŃ€ĐŸĐ±ŃƒĐčтД Ń–ĐœŃˆŃƒ пару ĐșĐŸĐŽŃ–ĐČ Đ±Đ”Đ·ĐżĐ”ĐșĐž. Đ”Đ»Ń ŃƒŃĐżŃ–ŃˆĐœĐŸŃ— пДрДĐČірĐșĐž ĐŽĐŸŃŃ‚Đ°Ń‚ĐœŃŒĐŸ Đ·Đ±Ń–ĐłŃƒ ĐČ ĐŸĐŽĐœŃ–Đč парі.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Đ©ĐŸĐ± пДрДĐČірото ĐœĐ°ŃĐČĐœŃ–ŃŃ‚ŃŒ ĐœĐ°ŃĐșŃ€Ń–Đ·ĐœĐŸĐłĐŸ шофруĐČĐ°ĐœĐœŃ Đ· ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ”ĐŒ {name}, ĐżĐŸŃ€Ń–ĐČĐœŃĐčтД ĐœĐ°ĐČĐ”ĐŽĐ”ĐœŃ– ĐČОщД цофро Ń–Đ· Ń†ĐžŃ„Ń€Đ°ĐŒĐž ĐœĐ° ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃ— ĐČĐ°ŃˆĐŸĐłĐŸ спіĐČŃ€ĐŸĐ·ĐŒĐŸĐČĐœĐžĐșа. ĐšĐŸŃ€ĐžŃŃ‚ŃƒĐČач таĐșĐŸĐ¶ ĐŒĐŸĐ¶Đ” ĐČіЮсĐșĐ°ĐœŃƒĐČато ĐČаш ĐșĐŸĐŽ за ĐŽĐŸĐżĐŸĐŒĐŸĐłĐŸŃŽ сĐČĐŸĐłĐŸ ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃŽ.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Đ—ĐŒŃ–ĐœĐž ĐœĐŸĐŒĐ”Ń€Ń–ĐČ Đ±Đ”Đ·ĐżĐ”ĐșĐž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ĐĐŸĐŒĐ”Ń€Đž бДзпДĐșĐž ĐŸĐœĐŸĐČĐ»ŃŽŃŽŃ‚ŃŒŃŃ ĐżŃ€ĐŸŃ‚ŃĐłĐŸĐŒ ĐżĐ”Ń€Đ”Ń…Ń–ĐŽĐœĐŸĐłĐŸ ĐżĐ”Ń€Ń–ĐŸĐŽŃƒ, Ń‰ĐŸĐ±Đž ĐœĐŸĐČі Ń„ŃƒĐœĐșції ĐșĐŸĐœŃ„Ń–ĐŽĐ”ĐœŃ†Ń–ĐčĐœĐŸŃŃ‚Ń– Signal ĐŒĐŸĐłĐ»Đž запрацюĐČато.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Đ©ĐŸĐ± пДрДĐČірото ĐșĐŸĐŽĐž бДзпДĐșĐž, ĐżĐŸŃ€Ń–ĐČĐœŃĐčтД ĐșĐŸĐ»ŃŒĐŸŃ€ĐŸĐČу ĐșартĐșу Đ· ĐșартĐșĐŸŃŽ ĐœĐ° ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃ— ĐČĐ°ŃˆĐŸĐłĐŸ ĐșĐŸĐœŃ‚Đ°Đșту. ĐŻĐșŃ‰ĐŸ цофро ĐœĐ” Đ·Đ±Ń–ĐłĐ°ŃŽŃ‚ŃŒŃŃ, ŃĐżŃ€ĐŸĐ±ŃƒĐčтД Ń–ĐœŃˆŃƒ пару ĐșĐŸĐŽŃ–ĐČ Đ±Đ”Đ·ĐżĐ”ĐșĐž. Đ”Đ»Ń ŃƒŃĐżŃ–ŃˆĐœĐŸŃ— пДрДĐČірĐșĐž ĐŽĐŸŃŃ‚Đ°Ń‚ĐœŃŒĐŸ Đ·Đ±Ń–ĐłŃƒ ĐČ ĐŸĐŽĐœŃ–Đč парі.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "ĐŸĐŸŃ‚Ń€Ń–Đ±ĐœĐ° ĐŽĐŸĐżĐŸĐŒĐŸĐłĐ°?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Đ—Ń€ĐŸĐ·ŃƒĐŒŃ–Đ»ĐŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ĐšĐŸĐŽ бДзпДĐșĐž Đ·'яĐČоться ĐżŃ–ŃĐ»Ń ĐŸĐ±ĐŒŃ–ĐœŃƒ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃĐŒĐž Ń–Đ· Ń†ĐžĐŒ ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ”ĐŒ.", @@ -1267,10 +1359,6 @@ "messageformat": "ДоĐČотось ĐœĐ”Ń‰ĐŸĐŽĐ°ĐČĐœŃ– ĐŒĐ”ĐŽŃ–Đ°", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Đ©ĐŸĐ± пДрДĐČірото бДзпДĐșу ĐČĐ°ŃˆĐŸĐłĐŸ ĐœĐ°ŃĐșŃ€Ń–Đ·ĐœĐŸĐłĐŸ шофруĐČĐ°ĐœĐœŃ Đ· ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ”ĐŒ {name}, ĐżĐŸŃ€Ń–ĐČĐœŃĐčтД ĐœĐ°ĐČĐ”ĐŽĐ”ĐœŃ– ĐČОщД цофро Ń–Đ· Ń†ĐžŃ„Ń€Đ°ĐŒĐž ĐœĐ° ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃ— ĐČĐ°ŃˆĐŸĐłĐŸ спіĐČŃ€ĐŸĐ·ĐŒĐŸĐČĐœĐžĐșа. ĐšĐŸŃ€ĐžŃŃ‚ŃƒĐČач таĐșĐŸĐ¶ ĐŒĐŸĐ¶Đ” ĐČіЮсĐșĐ°ĐœŃƒĐČато QR-ĐșĐŸĐŽ ĐČОщД.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "Во щД ĐœĐ” ĐŸĐ±ĐŒŃ–ĐœŃŽĐČĐ°Đ»ĐžŃŃ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃĐŒĐž Đ· ĐŽĐ°ĐœĐžĐŒĐž спіĐČŃ€ĐŸĐ·ĐŒĐŸĐČĐœĐžĐșĐŸĐŒ. ĐšĐŸĐŽ бДзпДĐșĐž ŃŃ‚Đ°ĐœĐ” ĐŽĐŸŃŃ‚ŃƒĐżĐœĐžĐč ĐżŃ–ŃĐ»Ń ĐżĐ”Ń€ŃˆĐŸĐłĐŸ ĐœĐ°ĐŽŃĐžĐ»Đ°ĐœĐœŃ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ." }, @@ -1334,17 +1422,17 @@ "messageformat": "Đ†ĐœŃ„ĐŸŃ€ĐŒĐ°Ń†Ń–Ń", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ВОЎалОтО", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ВОЎалОтО ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "ВОЎалОтО чат?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "ВОЎалОтО ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "Чат буЎД ĐČĐžĐŽĐ°Đ»Đ”ĐœĐŸ Đ· ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃŽ.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ĐŸĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ ĐČ Ń†ŃŒĐŸĐŒŃƒ чаті буЎД ĐČĐžĐŽĐ°Đ»Đ”ĐœĐŸ Đ· ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃŽ. Во Đ·ĐŒĐŸĐ¶Đ”Ń‚Đ” Đ·ĐœĐ°Đčто цДĐč чат ĐœĐ°ĐČіть ĐżŃ–ŃĐ»Ń ĐČĐžĐŽĐ°Đ»Đ”ĐœĐœŃ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœŃŒ.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ĐŸĐŸĐșĐžĐœŃƒŃ‚Đž групу", @@ -1438,6 +1526,14 @@ "messageformat": "Вашу Ń–ŃŃ‚ĐŸŃ€Ń–ŃŽ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœŃŒ ĐŽĐ»Ń ĐŸĐ±ĐŸŃ… чатіĐČ Đ±ŃƒĐ»ĐŸ ĐŸĐ±'Ń”ĐŽĐœĐ°ĐœĐŸ тут.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{conversationTitle} ĐČĐŸĐ»ĐŸĐŽŃ–Ń” ĐœĐŸĐŒĐ”Ń€ĐŸĐŒ {phoneNumber}. Во є ŃƒŃ‡Đ°ŃĐœĐžĐșĐ°ĐŒĐž цієї групо: {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{conversationTitle} ĐČĐŸĐ»ĐŸĐŽŃ–Ń” ĐœĐŸĐŒĐ”Ń€ĐŸĐŒ {phoneNumber}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ĐœŃ–ĐœŃ–Đ°Ń‚ŃŽŃ€ĐœŃ– Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ Đ· Ń†ĐžŃ‚ĐŸĐČĐ°ĐœĐžŃ… ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœŃŒ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ĐŸĐ”Ń€Đ”Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃƒĐČато", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ĐŸĐŸŃ‡Đ°Ń‚Đž ĐŽĐ·ĐČŃ–ĐœĐŸĐș", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ĐŸŃ€ĐžŃ”ĐŽĐœĐ°Ń‚ĐžŃŃŒ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "МіĐșŃ€ĐŸŃ„ĐŸĐœ ĐČĐžĐŒĐșĐœĐ”ĐœĐŸ чДрДз ĐČДлОĐșу ĐșŃ–Đ»ŃŒĐșість ŃƒŃ‡Đ°ŃĐœĐžĐșіĐČ ĐČĐžĐșлОĐșу", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ĐĄĐżĐŸĐČŃ–Ń‰Đ”ĐœĐœŃ ĐżŃ€ĐŸ ĐČĐžĐșлОĐșĐž", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "ДзĐČŃ–ĐœĐŸĐș ĐżĐŸĐČĐœĐžĐč", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ°", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ĐŸŃ€ĐžŃ”ĐŽĐœĐ°Ń‚ĐžŃŃŒ", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ĐŸĐŸŃ‡Đ°Ń‚Đž", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "ĐĐ”ĐŒĐ°Ń” ĐČŃ–Đ»ŃŒĐœĐžŃ… ĐŒŃ–ŃŃ†ŃŒ ĐŽĐ»Ń ĐŽĐ·ĐČŃ–ĐœĐșа", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ° ĐČĐžĐŒĐșĐœŃƒŃ‚Đ°", @@ -1621,10 +1725,6 @@ "messageformat": "ĐŁĐČŃ–ĐŒĐșĐœŃƒŃ‚Đž ĐșĐ°ĐŒĐ”Ń€Ńƒ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ĐĐ” ŃĐżĐŸĐČіщато", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "МіĐșŃ€ĐŸŃ„ĐŸĐœ ĐČĐžĐŒĐșĐœŃƒŃ‚ĐžĐč", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ĐŁĐČŃ–ĐŒĐșĐœŃƒŃ‚Đž ĐŒŃ–ĐșŃ€ĐŸŃ„ĐŸĐœ", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ĐŸĐŸĐŽŃ–Đ»ĐžŃ‚ĐžŃŃ", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ĐŸŃ€Đ”ĐŽŃŃ‚Đ°ĐČĐ»Đ”ĐœĐœŃ ĐČіЮĐșĐ»ŃŽŃ‡Đ”ĐœĐŸ", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Đ—ŃƒĐżĐžĐœĐžŃ‚Đž прДЎстаĐČĐ»Đ”ĐœĐœŃ", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "ĐąĐ”Đ»Đ”Ń„ĐŸĐœŃƒĐČато", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "Група заĐČДлОĐșа ĐŽĐ»Ń ĐŽĐ·ĐČŃ–ĐœĐșіĐČ Ń—Ń— ŃƒŃ‡Đ°ŃĐœĐžĐșĐ°ĐŒ.", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Đ”ĐŸĐ·ĐČĐŸĐ»ĐžŃ‚Đž ĐČĐžĐșлОĐșĐž", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Đ’ĐžĐŒĐșĐœŃƒŃ‚Đž ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ĐŁĐČŃ–ĐŒĐșĐœŃƒŃ‚Đž ĐŽĐ·ĐČŃ–ĐœĐŸĐș", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "Đ‘Ń–Đ»ŃŒŃˆĐ” ĐŸĐżŃ†Ń–Đč", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "Во", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ĐšĐ°ĐŒĐ”Ń€Đ° ĐČĐžĐŒĐșĐœĐ”ĐœĐ°", "description": "Label in the calling lobby indicating that your camera is off" @@ -2016,27 +2128,27 @@ "description": "Informational text displayed if a sync operation times out." }, "icu:timestamp_s": { - "messageformat": "зараз", + "messageformat": "Ń‰ĐŸĐčĐœĐŸ", "description": "Brief timestamp for messages sent less than a minute ago. Displayed in the conversation list and message bubble." }, "icu:timestamp_m": { - "messageformat": "1хĐČ", + "messageformat": "1 хĐČ", "description": "Brief timestamp for messages sent about one minute ago. Displayed in the conversation list and message bubble." }, "icu:timestamp_h": { - "messageformat": "1Đł", + "messageformat": "1 ĐłĐŸĐŽ", "description": "Brief timestamp for messages sent about one hour ago. Displayed in the conversation list and message bubble." }, "icu:hoursAgo": { - "messageformat": "{hours,number} ĐłĐŸĐŽ.", + "messageformat": "{hours,number} ĐłĐŸĐŽ", "description": "Contracted form of 'X hours ago' which works both for singular and plural" }, "icu:minutesAgo": { - "messageformat": "{minutes,number} хĐČ.", + "messageformat": "{minutes,number} хĐČ", "description": "Contracted form of 'X minutes ago' which works both for singular and plural" }, "icu:justNow": { - "messageformat": "Зараз", + "messageformat": "Đ©ĐŸĐčĐœĐŸ", "description": "Shown if a message is very recent, less than 60 seconds old" }, "icu:timestampFormat__long--today": { @@ -2147,6 +2259,10 @@ "messageformat": "ĐŸĐŸĐŽĐžĐČотось ĐșĐŸĐŽ бДзпДĐșĐž", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ĐŸĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "ĐŸĐŸĐŽĐžĐČотось ĐșĐŸĐŽ бДзпДĐșĐž", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃŒ Đ·ĐœĐ°Đčто ĐœĐŸĐŒĐ”Ń€ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃƒ. ĐŸĐ”Ń€Đ”ĐČіртД Đ·'Ń”ĐŽĐœĐ°ĐœĐœŃ та ŃĐżŃ€ĐŸĐ±ŃƒĐčтД щД.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "Đ’ĐœĐŸŃĐžŃ‚Đž Đ·ĐŒŃ–ĐœĐž ĐŒĐŸĐ¶ĐœĐ° ĐżŃ€ĐŸŃ‚ŃĐłĐŸĐŒ 3 ĐłĐŸĐŽĐžĐœ Ń–Đ· ĐŒĐŸĐŒĐ”ĐœŃ‚Ńƒ ĐœĐ°ĐŽŃĐžĐ»Đ°ĐœĐœŃ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "Đ’ĐœĐŸŃĐžŃ‚Đž Đ·ĐŒŃ–ĐœĐž ĐŒĐŸĐ¶ĐœĐ° ĐżŃ€ĐŸŃ‚ŃĐłĐŸĐŒ 24 ĐłĐŸĐŽĐžĐœ Ń–Đ· ĐŒĐŸĐŒĐ”ĐœŃ‚Ńƒ ĐœĐ°ĐŽŃĐžĐ»Đ°ĐœĐœŃ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ĐŠĐ” ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ Đ±ŃƒĐ»ĐŸ ĐČĐžĐŽĐ°Đ»Đ”ĐœĐŸ.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "ВĐșĐ»Đ°ĐŽĐ”ĐœĐžĐč фаĐčĐ» заĐČДлОĐșĐžĐč ĐŽĐ»Ń ĐČŃ–ĐŽĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Đ”Đ”ŃĐșі ĐČĐșĐ»Đ°ĐŽĐ”ĐœŃ– фаĐčлО заĐČДлОĐșі ĐŽĐ»Ń ĐČŃ–ĐŽĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃŒ ĐŸŃ‚Ń€ĐžĐŒĐ°Ń‚Đž ĐČŃ–ĐŽĐŸĐŒĐŸŃŃ‚Ń– ĐżŃ€ĐŸ ĐŽĐŸĐœĐ°Ń‚", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ĐąŃ–Đ»ŃŒĐșĐž ĐČ Đ±Đ”Ń‚Đ°-ĐČДрсії Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "РДЎагуĐČĐ°ĐœĐœŃ ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœŃŒ ĐŽĐŸŃŃ‚ŃƒĐżĐœĐŸ Ń‚Ń–Đ»ŃŒĐșĐž ĐŽĐ»Ń ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČачіĐČ Đ±Đ”Ń‚Đ°-ĐČДрсії Signal. ĐŻĐșŃ‰ĐŸ ĐČĐž ĐČŃ–ĐŽŃ€Đ”ĐŽĐ°ĐłŃƒŃ”Ń‚Đ” ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ, цД ĐżĐŸĐ±Đ°Ń‡Đ°Ń‚ŃŒ Ń‚Ń–Đ»ŃŒĐșĐž ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČачі ĐŸŃŃ‚Đ°ĐœĐœŃŒĐŸŃ— бДта-ĐČДрсії Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Đ—ĐŒŃ–ĐœĐžŃ‚Đž ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ĐŻĐșŃ‰ĐŸ ĐČĐž ĐČŃ–ĐŽŃ€Đ”ĐŽĐ°ĐłŃƒŃ”Ń‚Đ” ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ, ĐČĐŸĐœĐŸ буЎД ĐżĐŸĐșĐ°Đ·Đ°ĐœĐŸ Ń‚Ń–Đ»ŃŒĐșĐž ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ°ĐŒ ĐŸŃŃ‚Đ°ĐœĐœŃ–Ń… ĐČДрсіĐč Signal. йаĐșі ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČачі Đ·ĐŒĐŸĐ¶ŃƒŃ‚ŃŒ ĐżĐŸĐ±Đ°Ń‡ĐžŃ‚Đž, Ń‰ĐŸ ĐČĐž ĐČŃ–ĐŽŃ€Đ”ĐŽĐ°ĐłŃƒĐČалО ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3281,15 +3413,15 @@ "description": "Specifies the number of members in a group conversation" }, "icu:member-of-1-group": { - "messageformat": "ĐŸĐŸĐ»ŃĐłĐ°Ń” ĐČ {group}", + "messageformat": "Є ŃƒŃ‡Đ°ŃĐœĐžĐșĐŸĐŒ «{group}»", "description": "Shown in the conversation hero to indicate this user is a member of a mutual group" }, "icu:member-of-2-groups": { - "messageformat": "ĐŸĐŸĐ»ŃĐłĐ°Ń” ĐČ {group1} і {group2}", + "messageformat": "Є ŃƒŃ‡Đ°ŃĐœĐžĐșĐŸĐŒ «{group1}» і «{group2}»", "description": "Shown in the conversation hero to indicate this user is a member of two mutual groups" }, "icu:member-of-3-groups": { - "messageformat": "ĐŸĐŸĐ»ŃĐłĐ°Ń” ĐČ {group1}, {group2}, і {group3}", + "messageformat": "Є ŃƒŃ‡Đ°ŃĐœĐžĐșĐŸĐŒ «{group1}», «{group2}» і «{group3}»", "description": "Shown in the conversation hero to indicate this user is a member of three mutual groups" }, "icu:member-of-more-than-3-groups--one-more": { @@ -3380,6 +3512,14 @@ "messageformat": "Đ’Ń…Ń–ĐŽĐœĐžĐč ĐČŃ–ĐŽĐ”ĐŸĐČĐžĐșлОĐș
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč ĐČŃ–ĐŽĐ”ĐŸĐŽĐ·ĐČŃ–ĐœĐŸĐș", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃƒŃ” ĐČĐ°ĐŒ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ĐŸĐŸĐČŃ‚ĐŸŃ€ĐœĐ” Đ·â€™Ń”ĐŽĐœĐ°ĐœĐœŃâ€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} ĐŸŃĐŸĐ±Đž} few {{count,number} ĐŸŃŃ–Đ±} many {{count,number} ĐŸŃŃ–Đ±} other {{count,number} ĐŸŃŃ–Đ±}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Đ“ĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ĐšŃ–ĐœĐ”Ń†ŃŒ", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "ĐŸĐŸĐșĐžĐœŃƒŃ‚Đž", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "МіĐșŃ€ĐŸŃ„ĐŸĐœ ĐČĐžĐŒĐșĐœĐ”ĐœĐŸ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "МіĐșŃ€ĐŸŃ„ĐŸĐœ уĐČŃ–ĐŒĐșĐœĐ”ĐœĐŸ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "ДзĐČŃ–ĐœĐŸĐș уĐČŃ–ĐŒĐșĐœĐ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "ДзĐČŃ–ĐœĐŸĐș ĐČĐžĐŒĐșĐœĐ”ĐœĐŸ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ĐĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ", @@ -3468,13 +3668,25 @@ "messageformat": "ĐŸĐŸĐČĐœĐŸĐ”ĐșŃ€Đ°ĐœĐœĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ĐžŃŃ ĐœĐ° ĐČОЎ сітĐșĐž", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Đ—ĐŒŃ–ĐœĐžŃ‚Đž ĐČĐžĐłĐ»ŃĐŽ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ĐžŃŃ ĐœĐ° ĐČОЎ Ń€ĐŸĐ·ĐŒĐŸĐČĐ»ŃŃŽŃ‡ĐŸĐłĐŸ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "СітĐșа", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Đ‘Ń–Ń‡ĐœĐ° ĐżĐ°ĐœĐ”Đ»ŃŒ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ĐžĐżĐŸĐČіЮач у Ń†Đ”ĐœŃ‚Ń€Ń–", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Đ’ĐžĐłĐ»ŃĐŽ Đ·ĐŒŃ–ĐœĐ”ĐœĐŸ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "ĐŸĐŸĐșĐžĐœŃƒŃ‚Đž ĐŽĐ·ĐČŃ–ĐœĐŸĐș", @@ -3576,6 +3788,14 @@ "messageformat": "Đ”ĐŸĐ±Ń€Đ”", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ Đ·ĐŒŃ–ĐœĐžŃ‚Đž ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ĐŠĐ” ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ ĐŒĐŸĐ¶ĐœĐ° Đ·ĐŒŃ–ĐœĐžŃ‚Đž Ń‚Ń–Đ»ŃŒĐșĐž {max,number} разіĐČ.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ВОбачтД, цД ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ sgnl:// ĐœĐ” ĐŒĐ°Ń” ŃĐ”ĐœŃŃƒ!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -4577,11 +4797,11 @@ "description": "The button shown on a conversation details (for a direct contact) that you can click to add that contact to groups" }, "icu:ConversationDetailsGroups--show-all": { - "messageformat": "ĐŸĐŸĐ±Đ°Ń‡ĐžŃ‚Đž ĐČсД", + "messageformat": "Усі", "description": "This is a button on the conversation details (for a direct contact) to show all groups-in-common" }, "icu:ConversationNotificationsSettings__mentions__label": { - "messageformat": "ЗгаЮато", + "messageformat": "ЗгаЮĐșĐž", "description": "In the conversation notifications settings, this is the label for the mentions option" }, "icu:ConversationNotificationsSettings__mentions__info": { @@ -5252,10 +5472,30 @@ "messageformat": "Đ†ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "Із ĐČĐ°ŃˆĐžĐŒ Ń–ĐŒĐ”ĐœĐ”ĐŒ ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача ŃŃ‚Đ°Đ»Đ°ŃŃ ĐżĐŸĐŒĐžĐ»Đșа. Đ’ĐŸĐœĐŸ Đ±Ń–Đ»ŃŒŃˆĐ” ĐœĐ” ĐœĐ°Đ»Đ”Đ¶ĐžŃ‚ŃŒ ĐŽĐŸ ĐČĐ°ŃˆĐŸĐłĐŸ аĐșĐ°ŃƒĐœŃ‚Ńƒ.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ВОЎалОтО Ń–ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "СтĐČĐŸŃ€ĐžŃ‚Đž Ń–ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR-ĐșĐŸĐŽ чо ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Đ†ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ сĐșĐžĐœŃƒŃ‚Đž", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ĐŸĐŸŃĐžĐ»Đ°ĐœĐœŃ Ń–ĐŒĐ”ĐœŃ– ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ сĐșĐžĐœŃƒŃ‚Đž", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "ĐŸĐŸĐŽŃ–Đ»Ń–Ń‚ŃŒŃŃ сĐČĐŸŃ—ĐŒ Ń–ĐŒĐ”ĐœĐ”ĐŒ ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ВОЎалОтО Ń–ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ĐŠĐ” ĐČĐžĐ»ŃƒŃ‡ĐžŃ‚ŃŒ ĐČашД Ń–ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача та ĐŽĐŸĐ·ĐČĐŸĐ»ĐžŃ‚ŃŒ Ń–ĐœŃˆĐžĐŒ ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ°ĐŒ ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато ĐčĐŸĐłĐŸ. Во ĐČпДĐČĐœĐ”ĐœŃ–?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Đ†ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача буЎД ĐČĐžĐ»ŃƒŃ‡Đ”ĐœĐŸ, а QR-ĐșĐŸĐŽ і ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ — ĐČĐžĐŒĐșĐœĐ”ĐœĐŸ. Đ†ĐœŃˆŃ– ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČачі Đ·ĐŒĐŸĐ¶ŃƒŃ‚ŃŒ ĐČОбратО Ń–ĐŒ'я «{username}». ĐŸŃ€ĐŸĐŽĐŸĐČжОтО?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "Во Đ±Ń–Đ»ŃŒŃˆĐ” ĐœĐ” Đ·ĐŒĐŸĐ¶Đ”Ń‚Đ” ĐżŃƒĐ±Đ»Ń–ĐșуĐČато чо ĐżĐ”Ń€Đ”ĐłĐ»ŃĐŽĐ°Ń‚Đž ŃŃ‚ĐŸŃ€Ń–Đ·. ĐžĐœĐŸĐČĐ»Đ”ĐœĐœŃ ŃŃ‚ĐŸŃ€Ń–, яĐșі ĐČĐž ĐœĐ”Ń‰ĐŸĐŽĐ°ĐČĐœĐŸ ĐżŃƒĐ±Đ»Ń–ĐșуĐČалО, таĐșĐŸĐ¶ ĐČĐžĐŽĐ°Đ»ŃŃ‚ŃŒŃŃ.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ĐœĐŸĐČа", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ĐœĐŸĐČа", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "ĐœĐŸĐČа ŃĐžŃŃ‚Đ”ĐŒĐž", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ĐŸĐŸŃˆŃƒĐș ĐŒĐŸĐČĐž", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "ĐĐ”ĐŒĐ°Ń” Ń€Đ”Đ·ŃƒĐ»ŃŒŃ‚Đ°Ń‚Ń–ĐČ Đ·Đ° Đ·Đ°ĐżĐžŃ‚ĐŸĐŒ «{searchTerm}»", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Đ’ŃŃ‚Đ°ĐœĐŸĐČото", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "ĐŸĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚Ń–Ń‚ŃŒ Signal ĐŽĐ»Ń Đ·Đ°ŃŃ‚ĐŸŃŃƒĐČĐ°ĐœĐœŃ", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Đ©ĐŸĐ± ĐŒĐŸĐČа Đ·ĐŒŃ–ĐœĐžĐ»Đ°ŃŃ, ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ ĐżĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚Đž ĐżŃ€ĐŸĐłŃ€Đ°ĐŒŃƒ.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "ĐŸĐ”Ń€Đ”Đ·Đ°ĐżŃƒŃŃ‚ĐžŃ‚Đž", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "НаяĐČĐœĐ” ĐŸĐœĐŸĐČĐ»Đ”ĐœĐœŃ ĐŽĐŸ ĐČДрсії {version}", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ПіЮ час Đ·Đ±Đ”Ń€Đ”Đ¶Đ”ĐœĐœŃ ĐœĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœŃŒ ĐČĐžĐœĐžĐșла ĐżĐŸĐŒĐžĐ»Đșа. ĐĄĐżŃ€ĐŸĐ±ŃƒĐčтД ĐżŃ–Đ·ĐœŃ–ŃˆĐ”, Đ±ŃƒĐŽŃŒ ласĐșа.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ĐŸĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "Đ‘Ń–Đ»ŃŒŃˆĐ” стОліĐČ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ĐĄĐșĐžĐœŃƒŃ‚Đž", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Đ“ĐŸŃ‚ĐŸĐČĐŸ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ĐšĐŸĐ»Ń–Ń€ ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ Ń–ĐŒĐ”ĐœŃ– ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача, {index,number} Đ· {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ĐŻĐșŃ‰ĐŸ сĐșĐžĐœŃƒŃ‚Đž QR-ĐșĐŸĐŽ, ĐżĐŸŃ‚ĐŸŃ‡ĐœŃ– QR-ĐșĐŸĐŽ і ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ Đ±Ń–Đ»ŃŒŃˆĐ” ĐœĐ” працюĐČĐ°Ń‚ĐžĐŒŃƒŃ‚ŃŒ.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "ĐŸĐŸŃĐžĐ»Đ°ĐœĐœŃ сĐșоЮається
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR-ĐșĐŸĐŽ і ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ ĐœĐ” ĐČŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐŸ. ĐŸĐ”Ń€Đ”ĐČіртД піЮĐșĐ»ŃŽŃ‡Đ”ĐœĐœŃ ĐŽĐŸ ĐŒĐ”Ń€Đ”Đ¶Ń– і ŃĐżŃ€ĐŸĐ±ŃƒĐčтД Đ·ĐœĐŸĐČу.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Đ’ŃŃ‚Đ°ĐœĐŸĐČіть Ń–ĐŒ'я ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČача Signal", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "Đ·ĐŒŃ–ĐœĐ”ĐœĐŸ", + "messageformat": "Đ—ĐŒŃ–ĐœĐ”ĐœĐŸ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ĐĐ°ĐŽŃ–ŃĐ»Đ°Ń‚Đž Đ·ĐœĐŸĐČу", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "Đ†ĐœŃˆŃ– Юії", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "ВоĐșлОĐșĐž", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "ĐĐŸĐČĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "ĐĐŸĐČĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "Đ†ĐœŃˆŃ– Юії", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Очостото Ń–ŃŃ‚ĐŸŃ€Ń–ŃŽ ĐČĐžĐșлОĐșіĐČ", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Очостото Ń–ŃŃ‚ĐŸŃ€Ń–ŃŽ ĐČĐžĐșлОĐșіĐČ?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Щя Юія ĐœĐ°Đ·Đ°ĐČжЎО ĐČĐžĐŽĐ°Đ»ĐžŃ‚ŃŒ усю Ń–ŃŃ‚ĐŸŃ€Ń–ŃŽ ĐČĐžĐșлОĐșіĐČ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "ВОЎалОтО", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Đ†ŃŃ‚ĐŸŃ€Ń–ŃŽ ĐČĐžĐșлОĐșіĐČ ĐŸŃ‡ĐžŃ‰Đ”ĐœĐŸ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ĐĐ°Ń‚ĐžŃĐœŃ–Ń‚ŃŒ, Ń‰ĐŸĐ± ĐżĐ”Ń€Đ”ĐłĐ»ŃĐœŃƒŃ‚Đž Đ°Đ±ĐŸ Ń€ĐŸĐ·ĐżĐŸŃ‡Đ°Ń‚Đž ĐČĐžĐșлОĐș", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ĐŸĐŸŃˆŃƒĐș", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Đ€Ń–Đ»ŃŒŃ‚Ń€ за ĐżŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐžĐŒĐž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ĐŸĐ”Ń€Đ”ĐșлючОтО", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ĐĐ”ĐŒĐ°Ń” ĐœĐ”ĐŽĐ°ĐČĐœŃ–Ń… ĐČĐžĐșлОĐșіĐČ. ĐŸĐŸŃ‡ĐœŃ–Ń‚ŃŒ Ń–Đ· ĐŽĐ·ĐČŃ–ĐœĐșа Юругу.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "ĐĐ”ĐŒĐ°Ń” Ń€Đ”Đ·ŃƒĐ»ŃŒŃ‚Đ°Ń‚Ń–ĐČ Đ·Đ° Đ·Đ°ĐżĐžŃ‚ĐŸĐŒ «{query}»", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Đ’Ń…Ń–ĐŽĐœĐžĐč", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐžĐč", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Đ“Ń€ŃƒĐżĐŸĐČĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ĐĐ”ĐŒĐ°Ń” ĐœĐ”ĐŽĐ°ĐČĐœŃ–Ń… Ń€ĐŸĐ·ĐŒĐŸĐČ.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "ĐĐ”ĐŒĐ°Ń” Ń€Đ”Đ·ŃƒĐ»ŃŒŃ‚Đ°Ń‚Ń–ĐČ Đ·Đ° Đ·Đ°ĐżĐžŃ‚ĐŸĐŒ «{query}»", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș} other {Đ’Ń…Ń–ĐŽĐœĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș}}} Video {{direction, select, Outgoing {Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč ĐČŃ–ĐŽĐ”ĐŸĐŽĐ·ĐČŃ–ĐœĐŸĐș} other {Đ’Ń…Ń–ĐŽĐœĐžĐč ĐČŃ–ĐŽĐ”ĐŸĐŽĐ·ĐČŃ–ĐœĐŸĐș}}} Group {{direction, select, Outgoing {Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč ĐłŃ€ŃƒĐżĐŸĐČĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș} other {Đ’Ń…Ń–ĐŽĐœĐžĐč ĐłŃ€ŃƒĐżĐŸĐČĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș}}} other {{direction, select, Outgoing {Đ’ĐžŃ…Ń–ĐŽĐœĐžĐč ĐČĐžĐșлОĐș} other {Đ’Ń…Ń–ĐŽĐœĐžĐč ĐČĐžĐșлОĐș}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș} Video {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐžĐč ĐČŃ–ĐŽĐ”ĐŸĐŽĐ·ĐČŃ–ĐœĐŸĐș} Group {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐžĐč ĐłŃ€ŃƒĐżĐŸĐČĐžĐč ĐŽĐ·ĐČŃ–ĐœĐŸĐș} other {ĐŸŃ€ĐŸĐżŃƒŃ‰Đ”ĐœĐžĐč ĐČĐžĐșлОĐș}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Đ“ĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș бДз ĐČŃ–ĐŽĐżĐŸĐČіЮі} Video {Đ’Ń–ĐŽĐ”ĐŸĐŽĐ·ĐČŃ–ĐœĐŸĐș бДз ĐČŃ–ĐŽĐżĐŸĐČіЮі} Group {Đ“Ń€ŃƒĐżĐŸĐČĐžĐč ĐČĐžĐșлОĐș бДз ĐČŃ–ĐŽĐżĐŸĐČіЮі} other {ВоĐșлОĐș бДз ĐČŃ–ĐŽĐżĐŸĐČіЮі}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Đ’Ń–ĐŽŃ…ĐžĐ»Đ”ĐœĐžĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐžĐč ĐČĐžĐșлОĐș} Video {Đ’Ń–ĐŽŃ…ĐžĐ»Đ”ĐœĐžĐč ĐČŃ–ĐŽĐ”ĐŸĐČĐžĐșлОĐș} Group {Đ’Ń–ĐŽŃ…ĐžĐ»Đ”ĐœĐžĐč ĐłŃ€ŃƒĐżĐŸĐČĐžĐč ĐČĐžĐșлОĐș} other {Đ’Ń–ĐŽŃ…ĐžĐ»Đ”ĐœĐžĐč ĐČĐžĐșлОĐș}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {ЩД {count,number} пОшД.} few {ЩД {count,number} пошуть.} many {ЩД {count,number} пошуть.} other {ЩД {count,number} пОшД.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Đ©ĐŸ ĐœĐŸĐČĐŸĐłĐŸ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "Đ”Ń€Ń–Đ±ĐœŃ– ĐżĐŸĐ»Ń–ĐżŃˆĐ”ĐœĐœŃ, ĐČопраĐČĐ»Đ”ĐœĐœŃ ĐżĐŸĐŒĐžĐ»ĐŸĐș і ĐżĐŸĐșŃ€Đ°Ń‰Đ”ĐœĐœŃ Ń€ĐŸĐ±ĐŸŃ‚Đž Đ·Đ°ŃŃ‚ĐŸŃŃƒĐœĐșу. ДяĐșŃƒŃ”ĐŒĐŸ, Ń‰ĐŸ ĐČĐž Đ· Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ĐŠĐ” ĐŸĐœĐŸĐČĐ»Đ”ĐœĐœŃ ĐŒŃ–ŃŃ‚ĐžŃ‚ŃŒ ĐșŃ–Đ»ŃŒĐșа ĐżĐŸĐșŃ€Đ°Ń‰Đ”ĐœŃŒ ĐČŃ–ĐŽĐ”ĐŸĐČĐžĐșлОĐșіĐČ Ń– ĐłĐŸĐ»ĐŸŃĐŸĐČох ĐČĐžĐșлОĐșіĐČ, а таĐșĐŸĐ¶ ĐœĐ”ĐČДлОĐșі Đ·ĐŒŃ–ĐœĐž ĐŽĐŸĐșŃƒĐŒĐ”ĐœŃ‚Đ°Ń†Ń–Ń— (ЮяĐșŃƒŃ”ĐŒĐŸ, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "йДпДр ĐČĐž ĐŒĐŸĐ¶Đ”Ń‚Đ” Đ·ĐŒŃ–ĐœĐžŃ‚Đž ĐČĐžĐ±Ń€Đ°ĐœŃƒ ĐŒĐŸĐČу ĐČ Signal, ĐœĐ” Đ·ĐŒŃ–ĐœŃŽŃŽŃ‡Đž ŃĐžŃŃ‚Đ”ĐŒĐœŃ– ĐœĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ (ĐĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ Signal > Đ’ĐžĐłĐ»ŃĐŽ > ĐœĐŸĐČа)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "Мо Đ·ĐŒŃ–ĐœĐžĐ»Đž Đ·ĐœĐ°Ń‡ĐșĐž ŃĐżĐŸĐČŃ–Ń‰Đ”ĐœŃŒ, Ń‰ĐŸ Đ·'яĐČĐ»ŃŃŽŃ‚ŃŒŃŃ ĐČ ĐłŃ€ŃƒĐżĐŸĐČох ĐŸĐœĐŸĐČĐ»Đ”ĐœĐœŃŃ…, ĐœĐ°ĐżŃ€ĐžĐșлаЎ, ĐșĐŸĐ»Đž Ń…Ń‚ĐŸŃŃŒ ĐżŃ€ĐžŃ”ĐŽĐœŃƒŃ”Ń‚ŃŒŃŃ ĐŽĐŸ групо. йДпДр Đ·ĐœĐ°Ń‡ĐșĐž ĐČĐžĐŽĐœĐŸ ĐșращД, ĐŸŃĐŸĐ±Đ»ĐžĐČĐŸ ĐČ Ń‚Đ”ĐŒĐœĐŸĐŒŃƒ Ń€Đ”Đ¶ĐžĐŒŃ–. Мо Đ±Đ°Ń‡ĐžĐŒĐŸ, Ń‰ĐŸ Đ±Đ°ĐłĐ°Ń‚ŃŒĐŸŃ… Ń–Đ· ĐČас ціĐșаĐČоть Ń‚Đ”ĐŒŃ€ŃĐČа, Ń‚ĐŸĐ¶ тДпДр ĐČĐŸĐœĐ° буЎД щД ĐČĐžŃ€Đ°Đ·ĐœŃ–ŃˆĐŸŃŽ." + "icu:WhatsNew__v6.39--1": { + "messageformat": "Мо ĐČопраĐČОлО ĐșĐŸŃ€ĐŸŃ‚Đșу Đ·Đ°Ń‚Ń€ĐžĐŒĐșу, яĐșа Ń–ĐœĐŸĐŽŃ– ĐČĐžĐœĐžĐșала ĐœĐ° ĐżŃ€ĐžŃŃ‚Ń€ĐŸŃŃ… macOS піЮ час ĐżŃ€ĐžŃ”ĐŽĐœĐ°ĐœĐœŃ ĐŽĐŸ ĐČĐžĐșлОĐșу. На Đ¶Đ°Đ»ŃŒ, цД таĐșĐŸĐ¶ ĐŸĐ·ĐœĐ°Ń‡Đ°Ń” ĐŒŃ–ĐœŃƒŃ ĐŸĐŽĐœĐ” ĐČопраĐČĐŽĐ°ĐœĐœŃ за сДĐșŃƒĐœĐŽĐœĐ” Đ·Đ°ĐżŃ–Đ·ĐœĐ”ĐœĐœŃ ĐœĐ° Đ·ŃƒŃŃ‚Ń€Ń–Ń‡." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "Мо ĐČопраĐČОлО Đ°ĐœŃ–ĐŒĐ°Ń†Ń–ŃŽ ĐżĐ”Ń€Đ”Ń…ĐŸĐŽŃƒ у ĐČіĐșĐŸĐœŃ†ŃŃ… Ń–Đ· ĐČŃ–ĐŽĐ”ĐŸ, яĐșа ĐżŃ€ĐŸĐłŃ€Đ°Ń”Ń‚ŃŒŃŃ, ĐșĐŸĐ»Đž Ń…Ń‚ĐŸŃŃŒ ĐżŃ€ĐžŃ”ĐŽĐœŃƒŃ”Ń‚ŃŒŃŃ ĐŽĐŸ ĐłŃ€ŃƒĐżĐŸĐČĐŸĐłĐŸ ĐČĐžĐșлОĐșу Đ°Đ±ĐŸ ĐČĐžŃ…ĐŸĐŽĐžŃ‚ŃŒ Ń–Đ· ĐœŃŒĐŸĐłĐŸ." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "йДпДр ĐŒĐŸĐ¶ĐœĐ° ĐœĐ°Ń‚ĐžŃĐœŃƒŃ‚Đž ĐœĐ° Ń„ĐŸŃ‚ĐŸ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ чо аĐČатар групо ĐČ Ń‡Đ°Ń‚Ń–, Ń‰ĐŸĐ± ĐŸĐŽŃ€Đ°Đ·Ńƒ пДрДĐčто ĐČ ĐœĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ чату Đ°Đ±ĐŸ ĐżĐŸĐ±Đ°Ń‡ĐžŃ‚Đž ĐœĐ”ĐżĐ”Ń€Đ”ĐłĐ»ŃĐœŃƒŃ‚Ń– ŃŃ‚ĐŸŃ€Ń–Đ· у чаті. ДяĐșŃƒŃ”ĐŒĐŸ, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/ur/messages.json b/_locales/ur/messages.json index b2ac472120..c3ae997524 100644 --- a/_locales/ur/messages.json +++ b/_locales/ur/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "ڈیÙčۧ ŰšÛŒŰł Ű§ÛŒŰ±Ű±", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ڈیÙčۧ ŰšÛŒŰł میÚș Ù†Ù‚Ű” ÙˆŰ§Ù‚Űč ÛÙˆŰ§ ہے۔ ŰąÙŸ Ù†Ù‚Ű” کو Ú©Ű§ÙŸÛŒ ک۱ ŰłÚ©ŰȘے Ű§ÙˆŰ± Ù…ŰłŰŠÙ„Û’ کو Ùčڟیک Ú©Ű±Ù†Û’ میÚș Ù…ŰŻŰŻ کے لیے Signal ŰłÙŸÙˆŰ±Ùč ŰłÛ’ Ű±Ű§ŰšŰ·Û ک۱ ŰłÚ©ŰȘے ہیÚș۔ ۧگ۱ ŰąÙŸ کو ÙÙˆŰ±ÛŒ Ű·ÙˆŰ± ÙŸŰ± Signal ۧ۳ŰȘŰčÙ…Ű§Ù„ Ú©Ű±Ù†Ű§ ÛÛ’ŰŒ ŰȘو ŰąÙŸ Ű§ÙŸÙ†Ű§ ڈیÙčۧ Ű­Ű°Ù ک۱ ŰłÚ©ŰȘے ہیÚș Ű§ÙˆŰ± Ű±ÛŒ ۧ۳Ùčۧ۱Ùč ک۱ ŰłÚ©ŰȘے ہیÚș۔\n\nŰłÙŸÙˆŰ±Ùč ŰłÛ’ Ű±Ű§ŰšŰ·Û Ú©Ű±Ù†Û’ کے لیے Ù…Ù„Ű§Ű­ŰžÛ Ú©Ű±ÛŒÚș: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "۳ۧ۱ۧ ڈیÙčۧ Ű­Ű°Ù Ú©Ű±ÛŒÚș Ű§ÙˆŰ± ŰŻÙˆŰšŰ§Ű±Û ŰŽŰ±ÙˆŰč Ú©Ű±ÛŒÚș", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ڈیÙčۧ Ű­Ű°Ù Ú©Ű±ÛŒÚș Ű§ÙˆŰ± Ű±ÛŒ ۧ۳Ùčۧ۱Ùč Ú©Ű±ÛŒÚș", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "ŰȘÙ…Ű§Ù… ڈیÙčۧ کو Ù…ŰłŰȘقل Ű·ÙˆŰ± ÙŸŰ± Ű­Ű°Ù ک۱ ŰŻÛŒÚș۟", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "ۧ۳ ÚˆÛŒÙˆŰ§ŰŠŰł میÚș Ù…ÙˆŰŹÙˆŰŻ ŰąÙŸ کی ŰłŰ§Ű±ÛŒ Ù…ÛŒŰłŰŹ ÛŰłÙčŰ±ÛŒ Ű§ÙˆŰ± Ù…ÛŒÚˆÛŒŰ§ ÛÙ…ÛŒŰŽÛ کے لیے Ű­Ű°Ù ک۱ ŰŻÛŒŰ§ ŰŹŰ§ŰŠÛ’ ÚŻŰ§Û” ŰąÙŸ ۧ۳ ÚˆÛŒÙˆŰ§ŰŠŰł ÙŸŰ± Signal کو ŰŻÙˆŰšŰ§Ű±Û لنک Ú©Ű±Ù†Û’ کے ŰšŰčŰŻ Ű§ŰłÛ’ ۧ۳ŰȘŰčÙ…Ű§Ù„ Ú©Ű±Ù†Û’ کے Ù‚Ű§ŰšÙ„ ہوÚș ÚŻÛ’Û” ۧ۳ ۷۱ۭ ŰąÙŸ کے فون میÚș Ù…ÙˆŰŹÙˆŰŻ Ú©ÙˆŰŠÛŒ ŰšÚŸÛŒ ڈیÙčۧ Ű­Ű°Ù نہیÚș ہو ÚŻŰ§Û”", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "ŰąÙŸ کے ڈیÙčۧ ŰšÛŒŰł کۧ ÙˆŰ±Ú˜Ù† Signal کے ۧ۳ ÙˆŰ±Ú˜Ù† ŰłÛ’ ملŰȘۧ نہیÚș ہے۔ ۧ۳ ۚۧŰȘ کو یقینی ŰšÙ†Ű§ŰŠÛŒÚș کہ ŰąÙŸ Ű§ÙŸÙ†Û’ کمٟیوÙč۱ ÙŸŰ± Signal کۧ ŰȘۧŰČہ ŰȘŰ±ÛŒÙ† ÙˆŰ±Ú˜Ù† کڟول Ű±ÛÛ’ ہیÚș۔", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "Ű§ÙˆŰ± ÙŰ§ŰŠÙ„", @@ -300,6 +316,70 @@ "messageformat": "چیÙčŰł", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "ŰąÙŸ کے یوŰČ۱ نیم کے ۳ۧŰȘÚŸ Ú©Ú†ÚŸ ŰșÙ„Ű· ہو ÚŻÛŒŰ§ ÛÛ’ŰŒ یہ مŰČÛŒŰŻ ŰąÙŸ کے Ű§Ú©Ű§Ű€Ù†Ùč کے ۳ۧŰȘÚŸ ŰȘÙÙˆÛŒŰ¶ Ú©Ű±ŰŻÛ نہیÚș ہے۔ ŰąÙŸ ŰŻÙˆŰšŰ§Ű±Û Ú©ÙˆŰŽŰŽ ک۱ کے Ű§ŰłÛ’ ŰłÛŒÙč ک۱ ŰłÚ©ŰȘے ہیÚș ÛŒŰ§ Ù†ÛŒŰ§ منŰȘ۟ۚ ک۱ ŰłÚ©ŰȘے ہیÚș۔", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Ű§ŰšÚŸÛŒ Ùčڟیک Ú©Ű±ÛŒÚș", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "ŰąÙŸ کے QR کوڈ Ű§ÙˆŰ± یوŰČ۱ نیم لنک کے ۳ۧŰȘÚŸ Ú©Ú†ÚŸ Ù…ŰłŰŠÙ„Û ہو ÚŻÛŒŰ§ ŰȘÚŸŰ§ŰŒ یہ ۧۚ مŰČÛŒŰŻ Ù…ŰłŰȘÙ†ŰŻ نہیÚș Ű±ÛŰ§Û” ŰŻÙˆŰłŰ±ÙˆÚș کے ۳ۧŰȘÚŸ ŰŽÛŒŰŠŰ± Ú©Ű±Ù†Û’ کے لیے Ű§ÛŒÚ© Ù†ÛŒŰ§ لنک ŰšÙ†Ű§ŰŠÛŒÚș۔", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Ű§ŰšÚŸÛŒ Ùčڟیک Ú©Ű±ÛŒÚș", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "ÙčÛŒŰšŰČ ŰŻÚ©ÚŸŰ§ŰŠÛŒÚș", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "ÙčÛŒŰšŰČ Ú†ÚŸÙŸŰ§ŰŠÛŒÚș", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "Ű§ÛŒÚ© Ù†Ù‚Ű” ÙŸÛŒŰŽ ŰąÛŒŰ§", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} نہ ÙŸÚ‘ÚŸŰ§", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "نہ ÙŸÚ‘ÚŸŰ§ Ù†ŰŽŰ§Ù† ŰČŰŻ Ú©Ű±ŰŻÛ", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "چیÙčŰł", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Ú©Ű§Ù„ŰČ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ŰłÙčÙˆŰ±ÛŒŰČ", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "ŰȘ۱ŰȘÛŒŰšŰ§ŰȘ", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Signal Ű§ÙŸ ڈیÙč Ú©Ű±ÛŒÚș", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "ÙŸŰ±ÙˆÙŰ§ŰŠÙ„Â ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "ÙˆŰ§ÙŸŰł ŰŹŰ§ŰŠÛŒÚș", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "یہ چیÙčŰł ŰąŰ±Ú©Ű§ŰŠÛŒÙˆ Ú©Ű±ŰŻÛ ہیÚș Ű§ÙˆŰ± Ű”Ű±Ù Ù†ŰŠÛ’ Ù…ÛŒŰłŰŹŰČ Ù…ÙˆŰ”ÙˆÙ„ ہونے کی Ű”ÙˆŰ±ŰȘ میÚș Ű§Ù† ۚۧک۳ میÚș ŰžŰ§ÛŰ± ہوÚș ÚŻÛŒÛ”", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ÙˆÛŒŰłÛ’ ŰšÚŸÛŒ Ú©Ű§Ù„ Ú©Ű±ÛŒÚș", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ŰšÛŰ±Ű”ÙˆŰ±ŰȘ ŰŽŰ§Ù…Ù„ ہوÚș", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Ú©Ű§Ù„ ŰŹŰ§Ű±ÛŒ Ű±Ú©ÚŸÛŒÚș", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±ŰČ Ű§ÙŸ ڈیÙč کیے ۏۧ Ű±ÛÛ’ ہیÚș۔", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "مŰČÛŒŰŻ ÙŸÚ‘ÚŸÛŒÚș", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "ŰłŰ§ŰšÙ‚Û Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "Ű§ÚŻÙ„Ű§ Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ± ÙˆŰ±Ú˜Ù†ŰŒ {index,number} کُل {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "ŰȘŰ”ŰŻÛŒÙ‚ کے Ű·ÙˆŰ± ÙŸŰ± Ù†ŰŽŰ§Ù† Ù„ÚŻŰ§ŰŠÛŒÚș", @@ -663,33 +747,41 @@ "messageformat": "ŰȘŰ”ŰŻÛŒÙ‚ ہÙčŰ§ŰŠÛŒÚș", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "{name} کے ۳ۧŰȘÚŸ Ű§ÛŒÙ†Úˆ Ùčو Ű§ÛŒÙ†Úˆ Ű§Ù†Ú©Ű±ÙŸŰŽÙ† کی ŰȘŰ”ŰŻÛŒÙ‚ Ú©Ű±Ù†Û’ کے Ù„ÛŒÛ’ŰŒ Ű§ÙˆÙŸŰ± Ù…ÙˆŰŹÙˆŰŻ Ù†Ù…ŰšŰ±ŰČ Ú©Û’ ۳ۧŰȘÚŸ Ű§Ù† کی ÚˆÛŒÙˆŰ§ŰŠŰł کۧ Ù…ÙˆŰ§ŰČنہ Ú©Ű±ÛŒÚș۔ وہ Ű§ÙŸÙ†ÛŒ ÚˆÛŒÙˆŰ§ŰŠŰł کے ۳ۧŰȘÚŸ ŰąÙŸ کے کوڈ کو Ű§ŰłÚ©ÛŒÙ† ŰšÚŸÛŒ ک۱ ŰłÚ©ŰȘے ہیÚș۔", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "مŰČÛŒŰŻ ŰŹŰ§Ù†ÛŒÚș", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "{name} کے ۳ۧŰȘÚŸ Ű§ÛŒÙ†Úˆ Ùčو Ű§ÛŒÙ†Úˆ Ű§Ù†Ú©Ű±ÙŸŰŽÙ† کی ŰȘŰ”ŰŻÛŒÙ‚ Ú©Ű±Ù†Û’ کے Ù„ÛŒÛ’ŰŒ Ű§ÙˆÙŸŰ± Ù…ÙˆŰŹÙˆŰŻ Ú©Ù„Ű± کۧ۱ڈ کو Ű§Ù† کی ÚˆÛŒÙˆŰ§ŰŠŰł کے ۳ۧŰȘÚŸ میچ Ú©Ű±ÛŒÚș Ű§ÙˆŰ± Ù†Ù…ŰšŰ±ŰČ Ú©Ű§ Ù…ÙˆŰ§ŰČنہ Ú©Ű±ÛŒÚș۔ ۧگ۱ یہ میچ نہیÚș ک۱ŰȘÛ’ŰŒ ŰȘو Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±ŰČ Ú©Ű§ ŰŻÙˆŰłŰ±Ű§ ŰŹÙˆÚ‘Ű§ ŰąŰČÙ…Ű§ŰŠÛŒÚș۔ Ű”Ű±Ù Ű§ÛŒÚ© ŰŹÙˆÚ‘Û’ کو میچ Ú©Ű±Ù†Ű§ ہے۔", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "{name} کے ۳ۧŰȘÚŸ Ű§ÛŒÙ†Úˆ Ùčو Ű§ÛŒÙ†Úˆ Ű§Ù†Ú©Ű±ÙŸŰŽÙ† کی ŰȘŰ”ŰŻÛŒÙ‚ Ú©Ű±Ù†Û’ کے Ù„ÛŒÛ’ŰŒ Ű§ÙˆÙŸŰ± Ù…ÙˆŰŹÙˆŰŻ Ù†Ù…ŰšŰ±ŰČ Ú©Û’ ۳ۧŰȘÚŸ Ű§Ù† کی ÚˆÛŒÙˆŰ§ŰŠŰł کۧ Ù…ÙˆŰ§ŰČنہ Ú©Ű±ÛŒÚș۔ وہ Ű§ÙŸÙ†ÛŒ ÚˆÛŒÙˆŰ§ŰŠŰł کے ۳ۧŰȘÚŸ ŰąÙŸ کے کوڈ کو Ű§ŰłÚ©ÛŒÙ† ŰšÚŸÛŒ ک۱ ŰłÚ©ŰȘے ہیÚș۔", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±ŰČ Ù…ÛŒÚș ŰȘŰšŰŻÛŒÙ„ÛŒŰ§Úș", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "Signal میÚș ŰčÙ†Ù‚Ű±ÛŒŰš ŰžŰ§ÛŰ± ہونے ÙˆŰ§Ù„Û’ ÙŸŰ±Ű§ŰŠÛŒÙˆÛŒŰłÛŒ کے ÙÛŒÚ†Ű±ŰČ Ú©Ùˆ فŰčŰ§Ù„ Ú©Ű±Ù†Û’ کے لیے Ű§ÛŒÚ© ŰčŰšÙˆŰ±ÛŒ Ù…ŰŻŰȘ کے ŰŻÙˆŰ±Ű§Ù† Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±ŰČ Ú©Ùˆ Ű§ÙŸ ڈیÙč Ú©ÛŒŰ§ ۏۧ Ű±ÛŰ§ ہے۔", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±ŰČ Ú©ÛŒ ŰȘŰ”ŰŻÛŒÙ‚ Ú©Ű±Ù†Û’ کے Ù„ÛŒÛ’ŰŒ Ű§ÙŸÙ†Û’ Ű±Ű§ŰšŰ·Û’ کی ÚˆÛŒÙˆŰ§ŰŠŰł کے ۳ۧŰȘÚŸ Ű±Ù†ÚŻÛŒÙ† کۧ۱ڈ کو میچ Ú©Ű±ÛŒÚș۔ ۧگ۱ یہ میچ نہیÚș ک۱ŰȘÛ’ŰŒ ŰȘو Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ±ŰČ Ú©Ű§ ŰŻÙˆŰłŰ±Ű§ ŰŹÙˆÚ‘Ű§ ŰąŰČÙ…Ű§ŰŠÛŒÚș۔ Ű”Ű±Ù Ű§ÛŒÚ© ŰŹÙˆÚ‘Û’ کو میچ Ú©Ű±Ù†Ű§ ہے۔", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Ù…ŰŻŰŻ Ú†Ű§ÛÛŒÛ’ŰŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "ŰłÙ…ŰŹÚŸ ÚŻÛŒŰ§", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ۧ۳ ێ۟۔ کے ۳ۧŰȘÚŸ Ù…ÛŒŰłŰŹŰČ Ú©Ű§ ŰȘŰšŰ§ŰŻÙ„Û Ú©Ű±Ù†Û’ کے ŰšŰčŰŻ ۧ۳ کے ۳ۧŰȘÚŸ Ű§ÛŒÚ© Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ± ŰȘŰźÙ„ÛŒÙ‚ Ú©ÛŒŰ§ ŰŹŰ§ŰŠÛ’ ÚŻŰ§Û”", @@ -1267,10 +1359,6 @@ "messageformat": "Ű­Ű§Ù„ÛŒÛ Ù…ÛŒÚˆÛŒŰ§ ŰŻÛŒÚ©ÚŸÛŒÚș", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "{name} کے ۳ۧŰȘÚŸ Ű§ÙŸÙ†ÛŒ ŰŽŰ±ÙˆŰč ŰłÛ’ Ű§ÛŒÙ†Úˆ Ùčو Ű§ÛŒÙ†Úˆ Ù…Ű±Ù…ÙˆŰČ Ú©Ű§Ű±ÛŒ کی ŰłÛŒÚ©ÛŒÙˆŰ±Ùčی کی ŰȘŰ”ŰŻÛŒÙ‚ Ú©Ű±Ù†Û’ کے Ù„ÛŒÛ’ŰŒ Ű§ÙˆÙŸŰ± Ù…ÙˆŰŹÙˆŰŻ Ù†Ù…ŰšŰ±ŰČ Ú©Ű§ Ű§Ù† کی ÚˆÛŒÙˆŰ§ŰŠŰł کے ۳ۧŰȘÚŸ Ù…ÙˆŰ§ŰČنہ Ú©Ű±ÛŒÚș۔ وہ Ű§ÙˆÙŸŰ± Ù…ÙˆŰŹÙˆŰŻ qr کوڈ کو ŰšÚŸÛŒ Ű§ŰłÚ©ÛŒÙ† ک۱ ŰłÚ©ŰȘے ہیÚș۔", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "ŰąÙŸ نے Ű§ŰšÚŸÛŒ ŰȘÚ© ۧ۳ کنÙčÚ©Ùč کے ۳ۧŰȘÚŸ Ú©ŰłÛŒ ÙŸÛŒŰșŰ§Ù…Ű§ŰȘ کۧ ŰȘŰšŰ§ŰŻÙ„Û نہیÚș Ú©ÛŒŰ§ ہے۔ Ű§Ù† کے ۳ۧŰȘÚŸ ŰąÙŸ کۧ Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ± ٟہلے ÙŸÛŒŰșŰ§Ù… کے ŰšŰčŰŻ ŰŻŰłŰȘÛŒŰ§Űš ÛÙˆÚŻŰ§Û”" }, @@ -1334,17 +1422,17 @@ "messageformat": "مŰčÙ„ÙˆÙ…Ű§ŰȘ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "Ű­Ű°Ù Ú©Ű±ÛŒÚș", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "Ù…ÛŒŰłŰŹŰČ Ű­Ű°Ù Ú©Ű±ÛŒÚș", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "چیÙč کو Ű­Ű°Ù Ú©Ű±ÛŒÚș۟", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "Ù…ÛŒŰłŰŹŰČ Ű­Ű°Ù Ú©Ű±ÛŒÚș۟", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "یہ چیÙč ۧ۳ ÚˆÛŒÙˆŰ§ŰŠŰł ŰłÛ’ Ű­Ű°Ù ک۱ ŰŻÛŒ ŰŹŰ§ŰŠÛ’ ÚŻÛŒÛ”", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ۧ۳ چیÙč میÚș Ù…ÛŒŰłŰŹŰČ Ű§Űł ÚˆÛŒÙˆŰ§ŰŠŰł ŰłÛ’ Ű­Ű°Ù ہو ŰŹŰ§ŰŠÛŒÚș ÚŻÛ’Û” ŰąÙŸ Ù…ÛŒŰłŰŹŰČ Ű­Ű°Ù Ú©Ű±Ù†Û’ کے ŰšŰčŰŻ ŰšÚŸÛŒ ۧ۳ چیÙč کو ŰȘÙ„Ű§ŰŽ ک۱ ŰłÚ©ŰȘے ہیÚș۔", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "ÚŻŰ±ÙˆÙŸ Ú†ÚŸÙˆÚ‘ ŰŻÛŒÚș", @@ -1438,6 +1526,14 @@ "messageformat": "ŰŻÙˆÙ†ÙˆÚș چیÙčŰł کے لیے ŰąÙŸ کی Ù…ÛŒŰłŰŹ ÛŰłÙčŰ±ÛŒ ÛŒÛŰ§Úș Ű¶Ù… ک۱ ŰŻÛŒ ÚŻŰŠÛŒ ہے۔", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} کۧ ŰȘŰčلق {conversationTitle} ŰłÛ’ ہے۔ ŰąÙŸ ŰŻÙˆÙ†ÙˆÚș {sharedGroup} کے Ù…Ù…ŰšŰ±ŰČ ÛÛŒÚș۔", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} کۧ ŰȘŰčلق {conversationTitle} ŰłÛ’ ہے", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ŰȘŰ”ÙˆÛŒŰ± کے ŰȘÚŸÙ…Űš نیل ŰłÛ’ ÙŸÛŒŰșŰ§Ù… Ű­ÙˆŰ§Ù„Û’ Ú©Ű±ŰŻÛŒŰ§", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "ŰŻÙˆŰšŰ§Ű±Û Ú©Ű§Ù„ Ú©Ű±ÛŒÚș", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "Ú©Ű§Ù„ ŰŽŰ±ÙˆŰč Ú©Ű±ÛŒÚș", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Ú©Ű§Ù„ میÚș ŰŽŰ§Ù…Ù„ ہوÚș", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Ú©Ű§Ù„ کے ŰŻÙˆŰ±Ű§Ù†ÛŒÛ’ کی ÙˆŰŹÛ ŰłÛ’ Ù…Ű§ŰŠÛŒÚ©Ű±ÙˆÙÙˆÙ† ŰźŰ§Ù…ÙˆŰŽ ک۱ ŰŻÛŒŰ§ ÚŻÛŒŰ§", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "Ú©Ű§Ù„ کی Ű§Ű·Ù„Ű§ŰčۧŰȘ", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Ú©Ű§Ù„ ÙŸÙˆŰ±ÛŒ ہے", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "Ú©ÛŒÙ…Ű±Û", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "ŰŽŰ§Ù…Ù„ ہوÚș", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ŰŽŰ±ÙˆŰč Ú©Ű±ÛŒÚș", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Ú©Ű§Ù„ فل ہے", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Ú©ÛŒÙ…Ű±Ű§ ŰșÛŒŰ± فŰčŰ§Ù„ ÛÙˆÚŻÛŒŰ§", @@ -1621,10 +1725,6 @@ "messageformat": "Ú©ÛŒÙ…Ű±Ű§ ŰąÙ† Ú©Ű±ÛŒÚș", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "ŰźŰ§Ù…ÙˆŰŽ Ú©Ű±ÛŒÚș", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Ù…Ű§ŰŠÚ©Ű±ÙˆÙÙˆÙ† ŰșÛŒŰ± فŰčŰ§Ù„ ہے", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Ù…Ű§ŰŠÛŒÚ© کو ŰșÛŒŰ± ŰźŰ§Ù…ÙˆŰŽ Ú©Ű±ÛŒÚș", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "ۧێŰȘ۱ۧک Ú©Ű±ÛŒÚș", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ÙŸÛŒŰŽ Ú©Ű±Ù†Ű§ ŰșÛŒŰ± فŰčŰ§Ù„ ہے", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ÙŸÛŒŰŽ Ú©Ű±Ù†Ű§ ŰšÙ†ŰŻ Ú©Ű±ÛŒÚș", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Ú©Ű§Ù„ Ú©Ű±ÛŒÚș", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ێ۱کۧۥ کو Ú©Ű§Ù„ Ú©Ű±Ù†Û’ کے لیے ÚŻŰ±ÙˆÙŸ ŰšÛŰȘ ۹ڑۧ ہے۔", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Ú©Ű§Ù„ کے ŰšŰŹÙ†Û’ کو فŰčŰ§Ù„ Ú©Ű±ÛŒÚș", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "Ű±Ù†ÚŻÙ†ÚŻ ŰąÙ Ú©Ű±ÛŒÚș", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Ű±Ù†ÚŻÙ†ÚŻ ŰąÙ† Ú©Ű±ÛŒÚș", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "مŰČÛŒŰŻ ŰąÙŸŰŽÙ†ŰČ", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "ŰąÙŸ", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "ŰąÙŸ کۧ Ú©ÛŒÙ…Ű±Ű§ ŰšÙ†ŰŻ ہے", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ± ŰŻÛŒÚ©ÚŸÛŒÚș", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Ù…ÛŒŰłŰŹ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Ű­ÙŰ§ŰžŰȘی Ù†Ù…ŰšŰ± ŰŻÛŒÚ©ÚŸÛŒÚș", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "فون Ù†Ù…ŰšŰ± ڈڟونڈنے میÚș Ù†Ű§Ú©Ű§Ù…ÛŒ ÛÙˆŰŠÛŒÛ” Ű§ÙŸÙ†Ű§ Ú©Ù†Ú©ŰŽÙ† چیک Ú©Ű±ÛŒÚș Ű§ÙˆŰ± ŰŻÙˆŰšŰ§Ű±Û Ú©ÙˆŰŽŰŽ Ú©Ű±ÛŒÚș۔", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ŰąÙŸ کی Ű·Ű±Ù ŰłÛ’ ۧ۳ Ù…ÛŒŰłŰŹ کو ŰšÚŸÛŒŰŹÙ†Û’ کے ŰšŰčŰŻ ŰȘŰ±Ű§Ù…ÛŒÙ… Ù…Ű­Ű¶ 3 ÚŻÚŸÙ†ÙčوÚș کے Ű§Ù†ŰŻŰ± کی ۏۧ ŰłÚ©ŰȘی ہیÚș۔", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ŰąÙŸ کی Ű·Ű±Ù ŰłÛ’ ۧ۳ Ù…ÛŒŰłŰŹ کو ŰšÚŸÛŒŰŹÙ†Û’ کے ŰšŰčŰŻ ŰȘŰ±Ű§Ù…ÛŒÙ… کۧ Ű§Ű·Ù„Ű§Ù‚ Ù…Ű­Ű¶ 24 ÚŻÚŸÙ†ÙčوÚș کے Ű§Ù†ŰŻŰ± Ú©ÛŒŰ§ ۏۧ ŰłÚ©ŰȘۧ ہے۔", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "یہ ÙŸÛŒŰșŰ§Ù… Ű­Ű°Ù Ú©Ű±ŰŻÛŒŰ§ ÚŻÛŒŰ§ ŰȘÚŸŰ§Û”", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "Ù…Ù†ŰłÙ„Ú©Û ŰšÛŰȘ ŰšÚ‘ÛŒ ہے کہ ŰžŰ§ÛŰ± کی ۏۧ ŰłÚ©Û’Û”", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "Ú©Ú†ÚŸ Ù…Ù†ŰłÙ„Ú©Ű§ŰȘ ŰšÛŰȘ ŰšÚ‘ÛŒ ہیÚș کہ ÚˆŰłÙŸÙ„Û’ کی ۏۧ ŰłÚ©ÛŒÚș۔", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ŰčŰ·ÛŒÛ’ کی ŰȘÙŰ”ÛŒÙ„Ű§ŰȘ Ű­Ű§Ű”Ù„ Ú©Ű±Ù†Û’ ŰłÛ’ Ù‚Ű§Ű”Ű± ہیÚș", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Ű”Ű±Ù Signal ŰšÛŒ Ùčۧ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "Ù…ÛŒŰłŰŹŰČ Ù…ÛŒÚș ŰȘŰ±Ù…ÛŒÙ… Ú©Ű±Ù†Û’ کۧ ŰąÙŸŰŽÙ† Ű”Ű±Ù ŰłÚŻÙ†Ù„ ŰšÛŒ Ùčۧ یوŰČ۱ŰČ Ú©Û’ لیے ŰŻŰłŰȘÛŒŰ§Űš ہے۔ ۧگ۱ ŰąÙŸ Ú©ŰłÛŒ Ù…ÛŒŰłŰŹ میÚș ŰȘŰ±Ù…ÛŒÙ… ک۱ŰȘے ہیÚșی ŰȘو یہ Ű”Ű±Ù Ű§Ù† Ù„ÙˆÚŻÙˆÚș کو Ù†ŰžŰ± ŰąŰŠÛ’ ÚŻÛŒ ŰŹÙˆ ŰłÚŻÙ†Ù„ ŰšÛŒ Ùčۧ کۧ ŰȘۧŰČہ ŰȘŰ±ÛŒÙ† ÙˆŰ±Ú˜Ù† ۧ۳ŰȘŰčÙ…Ű§Ù„ ک۱ŰȘے ہیÚș۔", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Ù…ÛŒŰłŰŹ میÚș ŰȘŰ±Ù…ÛŒÙ… Ú©Ű±ÛŒÚș", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ۧگ۱ ŰąÙŸ Ú©ŰłÛŒ Ù…ÛŒŰłŰŹ میÚș ŰȘŰŻÙˆÛŒÙ† ک۱ŰȘے ہیÚșی ŰȘو یہ Ű”Ű±Ù Ű§Ù† Ù„ÙˆÚŻÙˆÚș کو Ù†ŰžŰ± ŰąŰŠÛ’ ÚŻÛŒ ŰŹÙˆ Signal کے ŰȘۧŰČہ ŰȘŰ±ÛŒÙ† ÙˆŰ±Ú˜Ù†ŰČ ÙŸŰ± ہیÚș۔ وہ یہ ŰŻÛŒÚ©ÚŸ ŰłÚ©ÛŒÚș ÚŻÛ’ کہ ŰąÙŸ نے Ú©ŰłÛŒ Ù…ÛŒŰłŰŹ میÚș ŰȘŰ±Ù…ÛŒÙ… کی ہے۔", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "ŰąÙ†Û’ ÙˆŰ§Ù„ÛŒ ویڈیو Ú©Ű§Ù„â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "۹ۀÙč ÚŻÙˆŰŠÙ†ÚŻ ÙˆŰ§ŰŠŰł Ú©Ű§Ù„", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "۹ۀÙč ÚŻÙˆŰŠÙ†ÚŻ ویڈیو Ú©Ű§Ù„", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ŰąÙŸ کو Ú©Ű§Ù„ ک۱ Ű±ÛŰ§/Ű±ÛÛŒ ہے", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "ŰŻÙˆŰšŰ§Ű±Û Ù…Ù†ŰłÙ„Ú© ہو Ű±ÛŰ§ ہے ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, one {{count,number} ÙŰ±ŰŻ} other {{count,number} Ű§ÙŰ±Ű§ŰŻ}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "ŰąÚˆÛŒÙˆ Ú©Ű§Ù„", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "ŰźŰȘم Ú©Ű±ÛŒÚș", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "نکل ŰŹŰ§ŰŠÛŒÚș", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "Ù…Ű§ŰŠÛŒÚ© ŰąÙ", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Ù…Ű§ŰŠÛŒÚ© ŰąÙ†", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Ű±Ù†ÚŻÙ†ÚŻ ŰąÙ†", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Ű±Ù†ÚŻÙ†ÚŻ ŰąÙ", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "ŰȘ۱ŰȘÛŒŰšŰ§ŰȘ", @@ -3468,13 +3668,25 @@ "messageformat": "فل ŰłÚ©Ű±ÛŒÙ† Ú©Ű§Ù„", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "گ۱ڈ Ù…Ù†ŰžŰ± ÙŸŰ± ŰłÙˆŰŠÚ† Ú©Ű±ÛŒÚș", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "ویو ŰȘŰšŰŻÛŒÙ„ Ú©Ű±ÛŒÚș", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Speaker view ÙŸŰ± ŰłÙˆŰŠÚ† Ú©Ű±ÛŒÚș", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "گ۱ڈ ویو", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ŰłŰ§ŰŠÛŒÚˆ ۚۧ۱ ویو", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Ű§ŰłÙŸÛŒÚ©Ű± ویو", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ویو Ű§ÙŸ ڈیÙč ہو ÚŻÛŒŰ§", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Ú©Ű§Ù„ Ú†ÚŸÙˆÚ‘Ùˆ", @@ -3576,6 +3788,14 @@ "messageformat": "Ùčڟیک ہے", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "Ù…ÛŒŰłŰŹ میÚș ŰȘŰ±Ù…ÛŒÙ… نہیÚș کی ŰłÚ©ŰȘی", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ۧ۳ Ù…ÛŒŰłŰŹ ÙŸŰ± Ű”Ű±Ù {max,number} ŰȘŰ±Ű§Ù…ÛŒÙ… کۧ Ű§Ű·Ù„Ű§Ù‚ Ú©ÛŒŰ§ ۏۧ ŰłÚ©ŰȘۧ ہے۔", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "مŰč۰۱ŰȘ ی کہ sgnl: // لنک کۧ Ú©ÙˆŰŠÛŒ Ù…Ű·Ù„Űš نہیÚș!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "Ű”Ű§Ű±ÙÛŒ Ù†Ű§Ù…", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "ŰąÙŸ کے یوŰČ۱ نیم کے ۳ۧŰȘÚŸ Ú©Ú†ÚŸ ŰșÙ„Ű· ہو ÚŻÛŒŰ§ ÛÛ’ŰŒ یہ مŰČÛŒŰŻ ŰąÙŸ کے Ű§Ú©Ű§Ű€Ù†Ùč کے ۳ۧŰȘÚŸ ŰȘÙÙˆÛŒŰ¶ Ú©Ű±ŰŻÛ نہیÚș ہے۔", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "Ű”Ű§Ű±ÙÛŒ Ù†Ű§Ù… Ű­Ű°Ù Ú©Ű±ÛŒÚș", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "Ű”Ű§Ű±Ù Ú©Ű§Ù… Ù†Ű§Ù… ŰšÙ†Ű§ŰŠÛŒÚș", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "QR کوڈ ÛŒŰ§ لنک", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "یوŰČ۱ نیم کو Ű±ÛŒ ŰłÛŒÙč Ú©Ű±Ù†Û’ کی Ű¶Ű±ÙˆŰ±ŰȘ ہے", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "یوŰČ۱ نیم لنک کو Ű±ÛŒ ŰłÛŒÙč Ú©Ű±Ù†Û’ کی Ű¶Ű±ÙˆŰ±ŰȘ ہے", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Ű§ÙŸÙ†Ű§ یوŰČ۱ نیم ŰŽÛŒŰŠŰ± Ú©Ű±ÛŒÚș", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "Ű”Ű§Ű±ÙÛŒ Ù†Ű§Ù… Ű­Ű°Ù Ú©Ű±ÛŒÚș", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "یہ ŰąÙŸ کۧ Ű”Ű§Ű±ÙÛŒ Ù†Ű§Ù… ہÙčۧ ŰŻÛ’ گۧی Ű§ÙˆŰ± ŰŻÛŒÚŻŰ± Ű”Ű§Ű±ÙÛŒÙ† کو ۧ۳ کۧ ŰŻŰčویٰ Ú©Ű±Ù†Û’ کی ۧۏۧŰČŰȘ ŰŻÛ’ ÚŻŰ§Û” Ú©ÛŒŰ§ ŰąÙŸ کو یقین ÛÛ’ŰŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "یہ ŰąÙŸ کۧ یوŰČ۱ نیم ہÙčۧ ŰŻÛ’ گۧ Ű§ÙˆŰ± ŰąÙŸ کے QR کوڈ Ű§ÙˆŰ± لنک کو ŰșÛŒŰ± فŰčŰ§Ù„ ک۱ ŰŻÛ’ ÚŻŰ§Û” \"{username}\" ŰŻÙˆŰłŰ±ÙˆÚș کو ŰŻŰčویٰ Ú©Ű±Ù†Û’ کے لیے ŰŻŰłŰȘÛŒŰ§Űš ہو ÚŻŰ§Û” Ú©ÛŒŰ§ ŰąÙŸ ÙˆŰ§Ù‚Űčی Ú©Ű±Ù†Ű§ Ú†Ű§ÛŰȘے ہیÚș۟", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "ŰąÙŸ مŰČÛŒŰŻ ŰłÙčÙˆŰ±ÛŒŰČ ŰŽÛŒŰŠŰ± Ú©Ű±Ù†Û’ ÛŒŰ§ ŰŻÛŒÚ©ÚŸÙ†Û’ ŰłÛ’ Ù‚Ű§Ű”Ű± ہوÚș ÚŻÛ’Û” ŰąÙŸ کی Ű·Ű±Ù ŰłÛ’ Ű­Ű§Ù„ÛŒÛ ŰŽÛŒŰŠŰ± Ú©Ű±ŰŻÛ ŰłÙčÙˆŰ±ÛŒ Ű§ÙŸ ڈیÙčŰł ŰšÚŸÛŒ ڈیلیÙč ہو ŰŹŰ§ŰŠÛŒÚș ÚŻÛŒÛ”", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "ŰČŰšŰ§Ù†", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "ŰČŰšŰ§Ù†", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "۳۳Ùčم کی ŰČŰšŰ§Ù†", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "ŰČŰšŰ§Ù†ÛŒÚș ŰȘÙ„Ű§ŰŽ Ú©Ű±ÛŒÚș", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "\"{searchTerm}\" کے لیے Ú©ÙˆŰŠÛŒ نŰȘۧۊۏ نہیÚș ہیÚș", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "ŰłÛŒÙč Ú©Ű±ÛŒÚș", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Ű§ŰłÛ’ Ù„Ű§ÚŻÙˆ Ú©Ű±Ù†Û’ کے لیے Signal کو Ű±ÛŒ ۧ۳ÙčۧÙč Ú©Ű±ÛŒÚș", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "ŰČŰšŰ§Ù† ŰȘŰšŰŻÛŒÙ„ Ú©Ű±Ù†Û’ کے Ù„ÛŒÛ’ŰŒ Ű§ÛŒÙŸ کو Ű±ÛŒ ۧ۳ÙčۧÙč Ú©Ű±Ù†Ű§ ÙŸÚ‘Û’ ÚŻŰ§Û”", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Ű±ÛŒ ۧ۳ÙčۧÙč Ú©Ű±ÛŒÚș", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "ÙˆŰ±Ú˜Ù† {version} ÙŸŰ± Ű§ÙŸ ڈیÙč ŰŻŰłŰȘÛŒŰ§Űš ہے", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ŰąÙŸ کی ŰȘ۱ŰȘÛŒŰšŰ§ŰȘ Ù…Ű­ÙÙˆŰž ک۱ŰȘے ÛÙˆŰŠÛ’ Ű§ÛŒÚ© Ù†Ù‚Ű” ÙˆŰ§Ù‚Űč ÛÙˆŰ§ ہے۔ ŰšŰ±Ű§Û Ú©Ű±Ù… ŰŻÙˆŰšŰ§Ű±Û Ú©ÙˆŰŽŰŽ Ú©Ű±ÛŒÚș۔", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Ù…ÛŒŰłŰŹ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "مŰČÛŒŰŻ ۧ۳ÙčŰ§ŰŠÙ„ŰČ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "ŰŻÙˆŰšŰ§Ű±Û ŰšŰ­Ű§Ù„ Ú©Ű±ÛŒÚș", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ہو ÚŻÛŒŰ§", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "یوŰČ۱ نیم کے لنک کۧ Ű±Ù†ÚŻŰŒ {index,number} کُل {total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ۧگ۱ ŰąÙŸ Ű§ÙŸÙ†Û’ QR کوڈ کو Ű±ÛŒ ŰłÛŒÙč ک۱ŰȘے ہیÚșی ŰȘو ŰąÙŸ کۧ Ù…ÙˆŰŹÙˆŰŻÛ QR کوڈ Ű§ÙˆŰ± لنک مŰČÛŒŰŻ Ú©Ű§Ù… نہیÚș Ú©Ű±ÛŒÚș ÚŻÛ’Û”", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "لنک Ű±ÛŒ ŰłÛŒÙč ہو Ű±ÛŰ§ ہے...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "QR کوڈ Ű§ÙˆŰ± لنک ŰłÛŒÙč نہیÚș ہیÚș۔ Ű§ÙŸÙ†Ű§ نیÙč ÙˆŰ±Ú© Ú©Ù†Ú©ŰŽÙ† چیک Ú©Ű±ÛŒÚș Ű§ÙˆŰ± ŰŻÙˆŰšŰ§Ű±Û Ú©ÙˆŰŽŰŽ Ú©Ű±ÛŒÚș۔", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Ű§ÙŸÙ†Ű§ Signal یوŰČ۱ نیم ŰłÛŒÙč Ű§ÙŸ Ú©Ű±ÛŒÚș", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "ŰȘŰ±Ù…ÛŒÙ… ہو ÚŻŰŠÛŒ", + "messageformat": "ŰȘŰ±Ù…ÛŒÙ… Ú©Ű±ŰŻÛ", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "ŰŻÙˆŰšŰ§Ű±Û ŰšÚŸÛŒŰŹÛŒÚș", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "مŰČÛŒŰŻ Ű§ÙŰčŰ§Ù„", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Ú©Ű§Ù„ŰČ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Ù†ŰŠÛŒ Ú©Ű§Ù„", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Ù†ŰŠÛŒ Ú©Ű§Ù„", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "مŰČÛŒŰŻ Ű§ÙŰčŰ§Ù„", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "Ú©Ű§Ù„ ÛŰłÙčŰ±ÛŒ کو Ú©Ù„ÙŠŰŠŰ± Ú©Ű±ÛŒÚș", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "Ú©Ű§Ù„ ÛŰłÙčŰ±ÛŒ کو Ú©Ù„ÙŠŰŠŰ± Ú©Ű±ÛŒÚș۟", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ۧ۳ ŰłÛ’ Ú©Ű§Ù„ کی ŰȘÙ…Ű§Ù… ÛŰłÙčŰ±ÛŒ Ù…ŰłŰȘقل Ű·ÙˆŰ± ÙŸŰ± Ű­Ű°Ù ہو ŰŹŰ§ŰŠÛ’ ÚŻÛŒ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "Ű”Ű§Ù", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Ú©Ű§Ù„ ÛŰłÙčŰ±ÛŒ Ű”Ű§Ù ک۱ ŰŻÛŒ ÚŻŰŠÛŒ", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ŰŻÛŒÚ©ÚŸÙ†Û’ کے لیے کلک Ú©Ű±ÛŒÚș ÛŒŰ§ Ú©Ű§Ù„ ŰŽŰ±ÙˆŰč Ú©Ű±ÛŒÚș", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "ŰȘÙ„Ű§ ‎ۮ ک۱ یÚș", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "ŰšÙ„Ű­Ű§Űž Ù…ŰłÚˆ فلÙč۱ Ú©Ű±ÛŒÚș", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ÙčÙˆÚŻÙ„ Ú©Ű±ÛŒÚș", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "Ú©ÙˆŰŠÛŒ Ű­Ű§Ù„ÛŒÛ Ú©Ű§Ù„ŰČ Ù†ÛÛŒÚș۔ ŰŻÙˆŰłŰȘ کو Ú©Ű§Ù„ Ú©Ű±Ù†Û’ کے Ű°Ű±ÛŒŰčے ŰąŰșۧŰČ Ú©Ű±ÛŒÚș۔", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "\"{query}\" کے لیے Ú©ÙˆŰŠÛŒ نŰȘۧۊۏ نہیÚș ہیÚș", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "ŰąÙ†Û’ ÙˆŰ§Ù„ÛŒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "ŰŹŰ§Ù†Û’ ÙˆŰ§Ù„ÛŒ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Ù…ŰłÚˆ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "Ú©ÙˆŰŠÛŒ Ű­Ű§Ù„ÛŒÛ ÚŻÙŰȘÚŻÙˆŰŠÛŒÚș نہیÚș۔", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "\"{query}\" کے لیے Ú©ÙˆŰŠÛŒ نŰȘۧۊۏ نہیÚș ہیÚș", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {۹ۀÙč ÚŻÙˆŰŠÙ†ÚŻ ÙˆŰ§ŰŠŰł Ú©Ű§Ù„} other {Ű§Ù† Ú©Ù…Ù†ÚŻ ÙˆŰ§ŰŠŰł Ú©Ű§Ù„}}} Video {{direction, select, Outgoing {۹ۀÙč ÚŻÙˆŰŠÙ†ÚŻ ویڈیو Ú©Ű§Ù„} other {ŰąÙ†Û’ ÙˆŰ§Ù„ÛŒ ویڈیو Ú©Ű§Ù„}}} Group {{direction, select, Outgoing {ŰŹŰ§Ù†Û’ ÙˆŰ§Ù„ÛŒ ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„} other {ŰąÙ†Û’ ÙˆŰ§Ù„ÛŒ ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„}}} other {{direction, select, Outgoing {کی ÚŻŰŠÛŒ Ú©Ű§Ù„} other {Ù…ÙˆŰ”ÙˆÙ„ ہونے ÙˆŰ§Ù„ÛŒ Ú©Ű§Ù„}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Ù…ŰłÚˆ ÙˆŰ§ŰŠŰł Ú©Ű§Ù„} Video {Ù…Űł ویڈیو Ú©Ű§Ù„} Group {Ù…Űł Ú©Ű±ŰŻÛ ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„} other {Ú©Ű§Ù„ Ù…Űł ہو ÚŻŰŠÛŒ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {ŰșÛŒŰ± ŰŹÙˆŰ§Űš ŰŽŰŻÛ ÙˆŰ§ŰŠŰł Ú©Ű§Ù„} Video {ŰșÛŒŰ± ŰŹÙˆŰ§Űš ŰŽŰŻÛ ویڈیو Ú©Ű§Ù„} Group {ŰșÛŒŰ± ŰŹÙˆŰ§Űš ŰŽŰŻÛ ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„} other {ŰșÛŒŰ± ŰŹÙˆŰ§Űš ŰŽŰŻÛ Ú©Ű§Ù„}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Ù…ŰłŰȘ۱ۯ Ú©Ű±ŰŻÛ ÙˆŰ§ŰŠŰł Ú©Ű§Ù„} Video {Ù…ŰłŰȘ۱ۯ Ú©Ű±ŰŻÛ ویڈیو Ú©Ű§Ù„} Group {Ù…ŰłŰȘ۱ۯ Ú©Ű±ŰŻÛ ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„} other {Ù…ŰłŰȘ۱ۯ Ú©Ű±ŰŻÛ Ú©Ű§Ù„}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, one {{count,number} ŰŻÙˆŰłŰ±Ű§ ÙčŰ§ŰŠÙŸ ک۱ Ű±ÛŰ§ ہے۔} other {{count,number} ŰŻÙˆŰłŰ±Û’ ÙčŰ§ŰŠÙŸ ک۱ Ű±ÛÛ’ ہیÚș۔}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "Ù†ÛŒŰ§ Ú©ÛŒŰ§ ہے", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "مŰčمولی ŰȘŰšŰŻÛŒÙ„ÛŒŰ§Úș کی ÚŻŰŠÛŒÚșی ŰšÚŻ Ùčڟیک کیے ÚŻŰŠÛ’ŰŒ Ű§ÙˆŰ± Ú©Ű§Ű±Ú©Ű±ŰŻÚŻÛŒ Ű§ÙˆŰ± ŰšÚŸÛŒ ŰšÛŰȘ۱ ŰšÙ†Ű§ŰŠÛŒ ÚŻŰŠÛŒ ہے۔ Signal ۧ۳ŰȘŰčÙ…Ű§Ù„ Ú©Ű±Ù†Û’ کے لیے ŰŽÚ©Ű±ÛŒÛ!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ۧ۳ Ű§ÙŸ ڈیÙč میÚș ÙˆŰ§ŰŠŰł Ű§ÙˆŰ± ویڈیو Ú©Ű§Ù„ŰČ Ú©Û’ لیے Ú©Ú†ÚŸ ŰšÛŰȘŰ±ÛŒŰ§Úșی Ű§ÙˆŰ± Ú©Ú†ÚŸ مŰčمولی ŰŻŰłŰȘŰ§ÙˆÛŒŰČی Ű§ÙŸ ڈیÙčŰł ŰŽŰ§Ù…Ù„ ہیÚș (ŰŽÚ©Ű±ÛŒÛŰŒ {linkToGithub}!)۔" + "icu:WhatsNew__v6.39--0": { + "messageformat": "ۧۚ ŰąÙŸ Ű§ÙŸÙ†ÛŒ ۳۳Ùčم ŰłÛŒÙčÙ†ÚŻŰČ Ú©Ùˆ ŰȘŰšŰŻÛŒÙ„ کیے ŰšŰșÛŒŰ± Signal میÚș Ű§ÙŸÙ†ÛŒ منŰȘ۟ۚ Ú©Ű±ŰŻÛ ŰČŰšŰ§Ù† ŰȘŰšŰŻÛŒÙ„ ک۱ ŰłÚ©ŰȘے ہیÚș (Signal ŰłÛŒÙčÙ†ÚŻŰČ > Ű±Ù†ÚŻ Ű±ÙˆÙŸ > ŰČŰšŰ§Ù†)۔" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ہم نے ÚŻŰ±ÙˆÙŸ کے Ú©Ú†ÚŸ Ű§Ű·Ù„Ű§ŰčۧŰȘی ŰąŰŠÛŒÚ©Ù†ŰČ Ú©Ùˆ Ű§ÙŸ ڈیÙč ک۱ ŰŻÛŒŰ§ ہے۔" + "icu:WhatsNew__v6.39--1": { + "messageformat": "ہم نے macOS ÙŸŰ± Ú©Ű§Ù„ Ù„Ű§ŰšÛŒ ŰŹÙˆŰ§ŰŠÙ† Ú©Ű±Ù†Û’ کے ŰšŰčŰŻ ŰšŰč۶ Ű§ÙˆÙ‚Ű§ŰȘ ÙŸÛŒŰŽ ŰąÙ†Û’ ÙˆŰ§Ù„Ű§ Ù…ŰźŰȘ۔۱ ŰȘŰ§ŰźÛŒŰ± کۧ Ù…ŰłŰŠÙ„Û Ùčڟیک ک۱ ŰŻÛŒŰ§ ہے۔" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ہم نے Ú©ŰłÛŒ Ù†ŰŠÛ’ ێ۟۔ کے ÚŻŰ±ÙˆÙŸ Ú©Ű§Ù„ میÚș ŰŽŰ§Ù…Ù„ ہونے ÙŸŰ± ÛŒŰ§ ۧ۳ ŰłÛ’ نکلنے ÙŸŰ± ویڈیو ÙčŰ§ŰŠÙ„ŰČ Ú©ÛŒ ÙčŰ±Ű§Ù†ŰČÛŒŰŽÙ† Ű§ÛŒÙ†ÛŒÙ…ÛŒŰŽÙ† کو Ùčڟیک ک۱ ŰŻÛŒŰ§ ہے۔" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "ۧۚ ŰąÙŸ چیÙč ŰłÛŒÙčÙ†ÚŻŰČ ŰȘÚ© ÙÙˆŰ±ÛŒ Ű±ŰłŰ§ŰŠÛŒ کے لیے چیÙč ÛÛŒÚˆŰ± میÚș ÙŸŰ±ÙˆÙŰ§ŰŠÙ„ فوÙčو ÛŒŰ§ ÚŻŰ±ÙˆÙŸ Ű§ÙˆŰȘۧ۱ ÙŸŰ± کلک ک۱ ŰłÚ©ŰȘے ہیÚș ÛŒŰ§ ۧ۳ چیÙč ŰłÛ’ Ú©ÙˆŰŠÛŒ ŰšÚŸÛŒ Ű§Ù† ŰŻÛŒÚ©ÚŸÛŒ ŰłÙčÙˆŰ±ÛŒŰČ ÙˆÛŒÙˆ ک۱ ŰłÚ©ŰȘے ہیÚș۔ ŰŽÚ©Ű±ÛŒÛŰŒ@!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/vi/messages.json b/_locales/vi/messages.json index 19b6efdaae..3bed1aa974 100644 --- a/_locales/vi/messages.json +++ b/_locales/vi/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "Lỗi CÆĄ sở dữ liệu", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "Đã xáșŁy ra lỗi cÆĄ sở dữ liệu. BáșĄn cĂł thể sao chĂ©p lỗi vĂ  liĂȘn hệ bộ pháș­n hỗ trợ cá»§a Signal để Ä‘Æ°á»Łc hỗ trợ kháșŻc phỄc váș„n đề. Náșżu báșĄn cáș§n sá»­ dỄng Signal ngay, báșĄn cĂł thể xĂła dữ liệu cá»§a mĂŹnh vĂ  khởi động láșĄi.\n\nLiĂȘn hệ với bộ pháș­n hỗ trợ báș±ng cĂĄch truy cáș­p: {link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "XĂła táș„t cáșŁ dữ liệu vĂ  khởi động láșĄi", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "XĂła dữ liệu vĂ  khởi động láșĄi", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "XĂła vÄ©nh viễn táș„t cáșŁ dữ liệu?", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "Táș„t cáșŁ lịch sá»­ tin nháșŻn vĂ  tệp đa phÆ°ÆĄng tiện cá»§a báșĄn sáșœ bị xĂła vÄ©nh viễn khỏi thiáșżt bị nĂ y. BáșĄn sáșœ cĂł thể sá»­ dỄng Signal trĂȘn thiáșżt bị nĂ y sau khi liĂȘn káșżt láșĄi. Thao tĂĄc nĂ y sáșœ khĂŽng xĂła báș„t kỳ dữ liệu nĂ o trĂȘn điện thoáșĄi cá»§a báșĄn.", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "PhiĂȘn báșŁn cÆĄ sở dữ liệu cá»§a báșĄn khĂŽng khớp với phiĂȘn báșŁn Signal nĂ y. ĐáșŁm báșŁo báșĄn đang sá»­ dỄng phiĂȘn báșŁn Signal mới nháș„t trĂȘn mĂĄy tĂ­nh cá»§a mĂŹnh.", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&Táș­p tin", @@ -300,6 +316,70 @@ "messageformat": "TrĂČ chuyện", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "CĂł váș„n đề với tĂȘn người dĂčng cá»§a báșĄn, tĂȘn nĂ y khĂŽng cĂČn gáșŻn liền với tĂ i khoáșŁn cá»§a báșĄn. BáșĄn cĂł thể thá»­ vĂ  đáș·t láșĄi hoáș·c chọn một tĂȘn mới.", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "Sá»­a ngay", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "CĂł váș„n đề với mĂŁ QR vĂ  đường dáș«n tĂȘn người dĂčng cá»§a báșĄn, tĂȘn nĂ y khĂŽng cĂČn kháșŁ dỄng. HĂŁy táșĄo đường dáș«n mới để chia sáș» với mọi người.", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "Sá»­a ngay", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "Hiển thị cĂĄc Tab", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "áșšn cĂĄc Tab", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "CĂł lỗi xáșŁy ra", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} chưa đọc", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "Đã đánh dáș„u chưa đọc", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "TrĂČ chuyện", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "Cuộc gọi", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "CĂĄc Story", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "CĂ i đáș·t", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "Cáș­p nháș­t Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "Hồ sÆĄ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "Trở láșĄi", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "CĂĄc cuộc trĂČ chuyện nĂ y đã Ä‘Æ°á»Łc lưu trữ vĂ  sáșœ chỉ hiện trong Hộp thư đáșżn náșżu cĂł tin nháșŻn mới Ä‘Æ°á»Łc nháș­n.", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "Váș«n gọi", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "Tiáșżp tỄc tham gia", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "Tiáșżp tỄc Cuộc gọi", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "CĂĄc mĂŁ số an toĂ n đang Ä‘Æ°á»Łc cáș­p nháș­t.", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "TĂŹm hiểu thĂȘm", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "MĂŁ số an toĂ n trước", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "MĂŁ số an toĂ n tiáșżp theo", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "PhiĂȘn báșŁn cá»§a mĂŁ số an toĂ n, {index,number} trĂȘn tổng số {total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "Đånh dáș„u đã xĂĄc minh", @@ -663,33 +747,41 @@ "messageformat": "XĂła xĂĄc nháș­n", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "Để xĂĄc minh báșŁo máș­t đáș§u cuối với {name}, hĂŁy so sĂĄnh cĂĄc số ở trĂȘn với thiáșżt bị cá»§a họ. Người đó cĆ©ng cĂł thể quĂ©t mĂŁ cá»§a báșĄn với thiáșżt bị cá»§a họ.", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "TĂŹm hiểu thĂȘm", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "Để xĂĄc minh báșŁo máș­t đáș§u cuối với {name}, hĂŁy khớp tháș» mĂ u nĂ y với thiáșżt bị cá»§a họ vĂ  so sĂĄnh cĂĄc số. Náșżu cĂĄc số nĂ y khĂŽng khớp, hĂŁy thá»­ cĂĄc cáș·p mĂŁ số an toĂ n khĂĄc. Chỉ cáș§n một cáș·p khớp nhau.", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "Để xĂĄc minh báșŁo máș­t đáș§u cuối với {name}, hĂŁy so sĂĄnh cĂĄc số ở trĂȘn với thiáșżt bị cá»§a họ. Người đó cĆ©ng cĂł thể quĂ©t mĂŁ cá»§a báșĄn với thiáșżt bị cá»§a họ.", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "CĂĄc thay đổi đối với MĂŁ số an toĂ n", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "CĂĄc mĂŁ số an toĂ n đang Ä‘Æ°á»Łc cáș­p nháș­t qua một giai đoáșĄn chuyển giao để hỗ trợ cĂĄc tĂ­nh năng quyền riĂȘng tư sáșŻp ra máșŻt trong Signal.", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "Để xĂĄc minh cĂĄc mĂŁ số an toĂ n, hĂŁy khớp tháș» mĂ u nĂ y với thiáșżt bị cá»§a liĂȘn hệ cá»§a báșĄn. Náșżu cĂĄc số nĂ y khĂŽng khớp, hĂŁy thá»­ cĂĄc cáș·p mĂŁ số an toĂ n khĂĄc. Chỉ cáș§n một cáș·p khớp nhau.", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "Cáș§n hỗ trợ?", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "Đã hiểu", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "Một mĂŁ số an toĂ n sáșœ Ä‘Æ°á»Łc táșĄo với người nĂ y sau khi hai báșĄn nháșŻn tin.", @@ -1267,10 +1359,6 @@ "messageformat": "Xem cĂĄc táș­p đa phÆ°ÆĄng tiện gáș§n đñy", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "Để xĂĄc minh báșŁo máș­t đáș§u cuối với {name}, hĂŁy so sĂĄnh cĂĄc số ở trĂȘn với thiáșżt bị cá»§a họ. Người đó cĆ©ng cĂł thể quĂ©t mĂŁ QR trĂȘn.", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "BáșĄn chưa trao đổi tin nháșŻn nĂ o với liĂȘn hệ nĂ y. Số an toĂ n cá»§a báșĄn với họ sáșœ Ä‘Æ°á»Łc cung cáș„p sau tin nháșŻn đáș§u tiĂȘn." }, @@ -1334,17 +1422,17 @@ "messageformat": "ThĂŽng tin", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "XĂła", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "XĂła tin nháșŻn", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "XĂła cuộc trĂČ chuyện?", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "XĂła tin nháșŻn?", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "TrĂČ chuyện nĂ y sáșœ bị xĂła khỏi thiáșżt bị nĂ y.", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "Tin nháșŻn trong cuộc trĂČ chuyện nĂ y sáșœ Ä‘Æ°á»Łc xĂła khỏi thiáșżt bị nĂ y. BáșĄn váș«n cĂł thể tĂŹm cuộc trĂČ chuyện nĂ y sau khi xĂła tin nháșŻn.", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "Rời nhĂłm", @@ -1367,7 +1455,7 @@ "description": "Conversation Header > Leave Group Action > Cannot Leave Group Because You Are Last Admin Alert > Description" }, "icu:sessionEnded": { - "messageformat": "Thiáșżt láș­p láșĄi phiĂȘn báșŁo máș­t", + "messageformat": "Đáș·t láșĄi phiĂȘn báșŁo máș­t", "description": "This is a past tense, informational message. In other words, your secure session has been reset." }, "icu:ChatRefresh--notification": { @@ -1438,6 +1526,14 @@ "messageformat": "Lịch sá»­ tin nháșŻn cá»§a cĂĄc cuộc trĂČ chuyện cá»§a báșĄn đã Ä‘Æ°á»Łc hợp nháș„t táșĄi đñy.", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} thuộc về {conversationTitle}. CĂĄc báșĄn đều lĂ  thĂ nh viĂȘn cá»§a {sharedGroup}.", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} thuộc về {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "HĂŹnh thu nhỏ cá»§a hĂŹnh áșŁnh từ tin nháșŻn Ä‘Æ°á»Łc trĂ­ch dáș«n", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "Gọi LáșĄi", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "BáșŻt đáș§u Cuộc gọi", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "Tham gia Cuộc gọi", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "Microphone bị táșŻt tiáșżng do kĂ­ch thước cuộc gọi quĂĄ lớn", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "ThĂŽng bĂĄo cuộc gọi", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "Cuộc gọi đã đáș§y", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "MĂĄy áșŁnh", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "Tham gia", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "BáșŻt đáș§u", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "Cuộc gọi đã đáș§y", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "Đã táșŻt Camera", @@ -1621,10 +1725,6 @@ "messageformat": "Báș­t camera", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "TáșŻt tiáșżng", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "Microphone đã Ä‘Æ°á»Łc táșŻt", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "Bỏ táșŻt tiáșżng micro", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "Chia sáș»", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "TáșŻt cháșż độ trĂŹnh bĂ y", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "Ngưng trĂŹnh bĂ y", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "Rung chuĂŽng", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "NhĂłm quĂĄ lớn để rung chuĂŽng cĂĄc thĂ nh viĂȘn", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "Báș­t đổ chuĂŽng", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "TáșŻt đổ chuĂŽng", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "Báș­t đổ chuĂŽng", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "TĂčy chọn khĂĄc", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "BáșĄn", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "Camera cá»§a báșĄn đang táșŻt", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "Xem Số An toĂ n", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "Tin nháșŻn", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "Xem Số An toĂ n", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "TĂŹm số điện thoáșĄi khĂŽng thĂ nh cĂŽng. HĂŁy kiểm tra đường truyền cá»§a báșĄn vĂ  thá»­ láșĄi.", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "CĂĄc chỉnh sá»­a chỉ cĂł thể Ä‘Æ°á»Łc thá»±c hiện trong vĂČng 3 giờ kể từ lĂșc báșĄn gá»­i tin nháșŻn nĂ y.", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "CĂĄc chỉnh sá»­a chỉ cĂł thể Ä‘Æ°á»Łc thá»±c hiện trong vĂČng 24 giờ kể từ lĂșc báșĄn gá»­i tin nháșŻn nĂ y.", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "Tin nháșŻn nĂ y đã bị xĂła.", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "KhĂŽng thể hiển thị tệp đính kĂšm vĂŹ quĂĄ lớn.", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "KhĂŽng thể hiển thị một số tệp đính kĂšm vĂŹ quĂĄ lớn.", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "KhĂŽng thể láș„y thĂŽng tin á»§ng hộ", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "Chỉ cĂł trĂȘn báșŁn beta cá»§a Signal", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "TĂ­nh năng sá»­a tin nháșŻn chỉ kháșŁ dỄng cho người dĂčng báșŁn beta cá»§a Signal. Náșżu báșĄn sá»­a một tin nháșŻn, nội dung sau khi thay đổi sáșœ chỉ hiển thị với người dĂčng báșŁn beta mới nháș„t cá»§a Signal.", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "Chỉnh sá»­a Tin nháșŻn", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "Náșżu báșĄn sá»­a một tin nháșŻn, thĂŽng tin về việc thay đổi sáșœ chỉ hiển thị với người dĂčng cĂĄc phiĂȘn báșŁn mới nháș„t cá»§a Signal. Những người dĂčng nĂ y sáșœ cĂł thể tháș„y báșĄn đã chỉnh sá»­a một tin nháșŻn.", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "CĂł cuộc gọi video đáșżn
", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "Cuộc gọi thoáșĄi đi", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "Cuộc gọi video đang gọi đi", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} đang gọi báșĄn", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "Đang káșżt nối láșĄi
", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} người}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "Cuộc gọi Ăąm thanh", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "Káșżt thĂșc", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "Rời", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "TáșŻt micro", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "Báș­t micro", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "Đổ chuĂŽng đang báș­t", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "Đổ chuĂŽng đang táșŻt", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "CĂ i đáș·t", @@ -3468,13 +3668,25 @@ "messageformat": "PhĂłng toĂ n mĂ n hĂŹnh cuộc gọi", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "Chuyển sang xem dáșĄng lưới", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "Đổi cháșż độ hiển thị", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "Chuyển sang xem người nĂłi", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "Hiển thị theo ĂŽ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "Hiển thị thanh bĂȘn", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "Hiển thị người phĂĄt biểu", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "Cháșż độ hiển thị đã cáș­p nháș­t", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "Rời cuộc gọi", @@ -3576,6 +3788,14 @@ "messageformat": "OK", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "KhĂŽng thể chỉnh sá»­a tin nháșŻn", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "Chỉ {max,number} chỉnh sá»­a cĂł thể Ä‘Æ°á»Łc ĂĄp dỄng cho tin nháșŻn nĂ y.", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "Xin lỗi, đường dáș«n sgnl:// khĂŽng đĂșng!", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -4181,7 +4401,7 @@ "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-reset--other": { - "messageformat": "{adminName} đã cĂ i láșĄi đường dáș«n nhĂłm.", + "messageformat": "{adminName} đã đáș·t láșĄi đường dáș«n nhĂłm.", "description": "Shown in timeline or conversation preview when v2 group changes" }, "icu:GroupV2--group-link-reset--unknown": { @@ -4605,11 +4825,11 @@ "description": "This lets users share their group link" }, "icu:GroupLinkManagement--confirm-reset": { - "messageformat": "BáșĄn cĂł muốn cĂ i láșĄi đường dáș«n nhĂłm? Người dĂčng khĂĄc sáșœ khĂŽng thể tham gia nhĂłm báș±ng đường dáș«n hiện táșĄi.", + "messageformat": "BáșĄn cĂł muốn đáș·t láșĄi đường dáș«n nhĂłm? Người dĂčng khĂĄc sáșœ khĂŽng thể tham gia nhĂłm báș±ng đường dáș«n hiện táșĄi.", "description": "Shown in the confirmation dialog when an admin is about to reset the group link" }, "icu:GroupLinkManagement--reset": { - "messageformat": "CĂ i láșĄi đường dáș«n", + "messageformat": "Đáș·t láșĄi đường dáș«n", "description": "This lets users generate a new group link" }, "icu:GroupLinkManagement--approve-label": { @@ -5029,19 +5249,19 @@ "description": "View title for the chat color picker and editor" }, "icu:ChatColorPicker__reset": { - "messageformat": "CĂ i láșĄi mĂ u cuộc trĂČ chuyện", + "messageformat": "Đáș·t láșĄi mĂ u cuộc trĂČ chuyện", "description": "Button label for resetting chat colors" }, "icu:ChatColorPicker__resetDefault": { - "messageformat": "CĂ i láșĄi cĂĄc MĂ u Cuộc trĂČ chuyện", + "messageformat": "Đáș·t láșĄi mĂ u cuộc trĂČ chuyện", "description": "Confirmation dialog title for resetting all chat colors or only the global default one" }, "icu:ChatColorPicker__resetAll": { - "messageformat": "CĂ i láșĄi táș„t cáșŁ cĂĄc mĂ u cuộc trĂČ chuyện", + "messageformat": "Đáș·t láșĄi táș„t cáșŁ mĂ u cuộc trĂČ chuyện", "description": "Button label for resetting all chat colors" }, "icu:ChatColorPicker__confirm-reset-default": { - "messageformat": "CĂ i láșĄi máș·c định", + "messageformat": "Đáș·t láșĄi máș·c định", "description": "Button label for resetting only global chat color" }, "icu:ChatColorPicker__confirm-reset": { @@ -5252,10 +5472,30 @@ "messageformat": "TĂȘn người dĂčng", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "CĂł váș„n đề với tĂȘn người dĂčng cá»§a báșĄn, tĂȘn nĂ y khĂŽng cĂČn gáșŻn liền với tĂ i khoáșŁn cá»§a báșĄn.", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "XĂła tĂȘn người dĂčng", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "TáșĄo TĂȘn người dĂčng", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "MĂŁ QR hoáș·c Đường Dáș«n", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "Cáș§n đáș·t láșĄi tĂȘn người dĂčng", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "Cáș§n đáș·t láșĄi đường dáș«n tĂȘn người dĂčng", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "Chia sáș» TĂȘn Người DĂčng cá»§a báșĄn", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "XĂła tĂȘn người dĂčng", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "Thao tĂĄc nĂ y sáșœ xĂła tĂȘn người dĂčng cá»§a báșĄn, cho phĂ©p người dĂčng khĂĄc xĂĄc nháș­n quyền sở hữu. BáșĄn cĂł cháșŻc khĂŽng?", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "Thao tĂĄc nĂ y sáșœ xĂła tĂȘn người dĂčng cá»§a báșĄn, đồng thời vĂŽ hiệu hĂła mĂŁ QR vĂ  đường dáș«n cá»§a báșĄn. \"{username}\" sáșœ cĂł thể Ä‘Æ°á»Łc sá»­ dỄng bởi thĂ nh viĂȘn khĂĄc. BáșĄn cĂł cháșŻc khĂŽng?", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "BáșĄn sáșœ khĂŽng thể tiáșżp tỄc chia sáș» hoáș·c xem story. CĂĄc cáș­p nháș­t story gáș§n đñy cá»§a báșĄn cĆ©ng sáșœ Ä‘Æ°á»Łc xĂła.", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "NgĂŽn ngữ", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "NgĂŽn ngữ", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "NgĂŽn ngữ Hệ thống", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "TĂŹm ngĂŽn ngữ", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "KhĂŽng cĂł káșżt quáșŁ cho “{searchTerm}”", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "Thiáșżt láș­p", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "Khởi động láșĄi Signal để ĂĄp dỄng", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "Để đổi ngĂŽn ngữ, cáș§n khởi động láșĄi ứng dỄng.", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "Khởi động láșĄi", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "Cáș­p nháș­t liĂȘn phiĂȘn báșŁn {version} cĂł sáș”n", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "Đã xáșŁy ra lỗi khi lưu cĂ i đáș·t cá»§a báșĄn. Vui lĂČng thá»­ láșĄi.", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "Tin nháșŻn", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "ThĂȘm phong cĂĄch", "description": "Action button for switching up the clock styles" @@ -6532,14 +6808,26 @@ "messageformat": "Đáș·t láșĄi", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "Xong", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "MĂ u cá»§a đường dáș«n tĂȘn người dĂčng, {index,number} cá»§a tổng số {total,number}", "description": "ARIA label of button for selecting username link color" }, "icu:UsernameLinkModalBody__reset__confirm": { - "messageformat": "Náșżu đáș·t láșĄi mĂŁ QR, mĂŁ QR vĂ  đường dáș«n hiện táșĄi cá»§a báșĄn sáșœ khĂŽng cĂČn hiệu lá»±c nữa.", + "messageformat": "Náșżu đáș·t láșĄi mĂŁ QR, mĂŁ QR vĂ  đường dáș«n thiện táșĄi cá»§a báșĄn sáșœ khĂŽng cĂČn hiệu lá»±c nữa.", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "Đang đáș·t láșĄi đường dáș«n
", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "MĂŁ QR vĂ  đường dáș«n chưa Ä‘Æ°á»Łc đáș·t. Kiểm tra káșżt nối máșĄng cá»§a báșĄn vĂ  thá»­ láșĄi.", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "Đáș·t tĂȘn người dĂčng Signal cá»§a báșĄn", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "đã chỉnh sá»­a", + "messageformat": "Đã chỉnh sá»­a", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "Gá»­i láșĄi", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "CĂĄc thao tĂĄc khĂĄc", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "Cuộc gọi", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "Cuộc gọi mới", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "Cuộc gọi mới", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "CĂĄc thao tĂĄc khĂĄc", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "XĂła lịch sá»­ cuộc gọi", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "XĂła lịch sá»­ cuộc gọi?", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "Thao tĂĄc nĂ y sáșœ xĂła vÄ©nh viễn táș„t cáșŁ lịch sá»­ cuộc gọi", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "XoĂĄ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "Đã xĂła lịch xá»­ cuộc gọi", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "Báș„m để xem hoáș·c báșŻt đáș§u cuộc gọi", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "TĂŹm kiáșżm", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "Lọc cuộc gọi nhụ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "Báș­t táșŻt", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "KhĂŽng cĂș gọi gáș§n đñy BáșŻt đáș§u với việc gọi cho một người báșĄn.", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "KhĂŽng cĂł káșżt quáșŁ cho “{query}”", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "Cuộc gọi đáșżn", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "Cuộc gọi đi", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "Cuộc gọi nhụ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "Cuộc gọi nhĂłm", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "KhĂŽng cĂł cuộc trĂČ chuyện gáș§n đñy.", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "KhĂŽng cĂł káșżt quáșŁ cho “{query}”", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {Cuộc gọi thoáșĄi đi} other {Cuộc gọi thoáșĄi đáșżn}}} Video {{direction, select, Outgoing {Cuộc gọi video đang gọi đi} other {Cuộc gọi video đang đáșżn}}} Group {{direction, select, Outgoing {Cuộc gọi nhĂłm đi} other {Cuộc gọi nhĂłm đáșżn}}} other {{direction, select, Outgoing {Cuộc gọi đi} other {Cuộc gọi đáșżn}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {Cuộc gọi thoáșĄi bị nhụ} Video {Cuộc gọi video bị nhụ} Group {Cuộc gọi nhĂłm bị nhụ} other {Cuộc gọi nhụ}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {Cuộc gọi thoáșĄi khĂŽng Ä‘Æ°á»Łc tráșŁ lời} Video {Cuộc gọi video khĂŽng Ä‘Æ°á»Łc tráșŁ lời} Group {Cuộc gọi nhĂłm khĂŽng Ä‘Æ°á»Łc tráșŁ lời} other {Cuộc gọi khĂŽng Ä‘Æ°á»Łc tráșŁ lời}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {Cuộc gọi thoáșĄi đã từ chối} Video {Cuộc gọi video đã từ chối} Group {Cuộc gọi nhĂłm đã từ chối} other {Cuộc gọi đã từ chối}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {{count,number} người khĂĄc đang nháș­p.}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "CĂł gĂŹ mới", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "CĂĄc tinh chỉnh, sá»­a lỗi, vĂ  cáșŁi thiện hiệu năng. CáșŁm ÆĄn báșĄn đã sá»­ dỄng Signal!", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "BáșŁn cáș­p nháș­t nĂ y bao gồm một số nĂąng cáș„p cho cuộc gọi thoáșĄi vĂ  cuộc gọi video cĂčng một số cáș­p nháș­t nhỏ cho pháș§n tĂ i liệu cá»§a ứng dỄng (xin cáșŁm ÆĄn, {linkToGithub}!)." + "icu:WhatsNew__v6.39--0": { + "messageformat": "Giờ đñy báșĄn cĂł thể thay đổi ngĂŽn ngữ đã chọn trong Signal mĂ  khĂŽng cáș§n thay đổi thiáșżt láș­p cá»§a hệ thống (CĂ i đáș·t Signal > Giao diện > NgĂŽn ngữ)." }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "ChĂșng tĂŽi đã cáș­p nháș­t một số biểu tÆ°á»Łng thĂŽng bĂĄo cá»§a nhĂłm." + "icu:WhatsNew__v6.39--1": { + "messageformat": "ChĂșng tĂŽi đã sá»­a lỗi đîi khi cĂł khoáșŁng thời gian trễ ngáșŻn khi vĂ o phĂČng cuộc gọi trĂȘn macOS." + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "ChĂșng tĂŽi đã sá»­a hiệu ứng động cá»§a cĂĄc ĂŽ video khi cĂł người tham gia hoáș·c rời cuộc gọi nhĂłm." + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "Giờ đñy báșĄn cĂł thể báș„m vĂ o áșŁnh hồ sÆĄ hoáș·c hĂŹnh đáșĄi diện cá»§a nhĂłm ở pháș§n phĂ­a trĂȘn cá»§a khung trĂČ chuyện để nhanh chĂłng vĂ o mỄc cĂ i đáș·t cuộc trĂČ chuyện hoáș·c xem cĂĄc story từ cuộc trĂČ chuyện đó mĂ  báșĄn chưa xem. CáșŁm ÆĄn, {linkToGithub}!" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/yue/messages.json b/_locales/yue/messages.json index 3fcaee782d..70fcab5ca3 100644 --- a/_locales/yue/messages.json +++ b/_locales/yue/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "èł‡æ–™ćș«éŒŻèȘ€", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "èł‡æ–™ćș«ç™Œç”ŸéŒŻèȘ€ă€‚äœ ćŻä»„è€‡èŁœéŒŻèȘ€ïŒŒç„¶ćŸŒèŻç”Ą Signal æ”ŻæŽćœ˜éšŠć諿‰‹è§Łæ±șć•éĄŒă€‚ćŠ‚æžœäœ éœ€èŠćłćˆ»ç”š SignalïŒŒćŻä»„éžæ“‡ćˆȘé™€èł‡æ–™ç„¶ćŸŒé‡æ–°ć•Ÿć‹•ă€‚\n\nèŠèŻç”Ąæ”ŻæŽćœ˜éšŠïŒŒè«‹ćŽ»ć‘ąćșŠïŒš{link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ćˆȘé™€æ‰€æœ‰èł‡æ–™ïŒŒç„¶ćŸŒé‡æ–°ć•Ÿć‹•", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ćˆȘé™€èł‡æ–™ïŒŒç„¶ćŸŒé‡æ–°ć•Ÿć‹•", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "係ć’Ș芁氞äč…ćˆȘé™€æ‰€æœ‰èł‡æ–™ć‘€ïŒŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "äœ ć˜…æ‰€æœ‰èšŠæŻçŽ€éŒ„ćŒćȘ’é«”ć°‡æœƒć–șć‘ąéƒšæ©ŸćșŠæ°žäč…ćˆȘé™€ă€‚é‡æ–°é€Łç”äč‹ćŸŒïŒŒäœ ć°±ćŻä»„ć–șć‘ąéƒšæ©ŸćșŠç”š Signal ć–‡ă€‚ć‘ąć€‹æ“äœœć””æœƒćˆȘé™€äœ æ‰‹æ©Ÿć˜…ä»»äœ•èł‡æ–™ă€‚", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "äœ ć˜…èł‡æ–™ćș«ç‰ˆæœŹćŒć‘ąć€‹ Signal ç‰ˆæœŹć””ç›žçŹŠă€‚è«‹çąșćźšäœ ć–șé›»è…Šç”šç·Šć˜…äż‚æœ€æ–°ç‰ˆæœŹć˜… Signal。", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "&File", @@ -300,6 +316,70 @@ "messageformat": "èŠć€©", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "äœ ć˜…ç”šæˆ¶ćçš±ć‡șçŸć•éĄŒïŒŒć””ć†æŒ‡ćźšè‡łäœ ć˜…ćžłæˆ¶ă€‚äœ ćŻä»„ć˜—è©Šé‡èš­æˆ–è€…éžæ“‡äž€ć€‹æ–°ć˜…ç”šæˆ¶ćçš±ă€‚", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ç«‹ćłäżźćŸ©", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "äœ ć˜…äșŒç¶­çąŒćŒç”šæˆ¶ćçš±é€Łç”ć‡șçŸć•éĄŒïŒŒć””ć†æœ‰æ•ˆă€‚ć»șç«‹æ–°é€Łç”ćˆ†äș«äżŸć…¶ä»–äșș敩。", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ç«‹ćłäżźćŸ©", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "饯ç€ș遞項暙籀", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "æ”¶ćŸ‹éžé …æš™ç±€", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ç™Œç”ŸéŒŻèȘ€", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} 怋æœȘèź€", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "æš™èš˜ćšæœȘèź€", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "èŠć€©", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "通話", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "é™æ™‚ć‹•æ…‹", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "èš­ćźš", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "曎新 Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "怋äșșæȘ”æĄˆ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "èż”èœ‰é ­", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "摱ć•ČèŠć€©ć·Čç¶“ć°ć­˜ïŒŒćȘ會ć–șæ”¶ćˆ°æ–°èšŠæŻć˜…æ™‚ć€™ć…ˆæœƒć–șæ”¶ä»¶çź±ć‡șçŸă€‚", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ç…§æšŁé€šè©±", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ç…§æšŁćŠ ć…„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "çčŒçșŒé€šè©±", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ćź‰ć…šçąŒæ›Žæ–°ç·Šă€‚", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "äș†è§Łć€šć•Č", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "äžŠäž€ç”„ćź‰ć…šçąŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "äž‹äž€ç”„ćź‰ć…šçąŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ćź‰ć…šçąŒç‰ˆæœŹïŒŒ{total,number} ć€‹ç•¶äž­ć˜…çŹŹ {index,number} 怋", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "æš™èš˜ćšć·Č驗證", @@ -663,33 +747,41 @@ "messageformat": "枅陀驗證", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "ćŠ‚æžœæƒłé©—è­‰äœ ćŒ {name} äč‹é–“ć˜…ç«Żć°ç«ŻćŠ ćŻ†èš­ćźšïŒŒäœ ćŻä»„ć°ć“äžŠéąć˜…è™ŸçąŒćŒäœąéƒšæ©Ÿć…„éąć˜…è™ŸçąŒă€‚äœąäșŠćŻä»„ç”šäœąéƒšæ©ŸæŽƒäœ ć˜…äșŒç¶­çąŒă€‚", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "äș†è§Łć€šć•Č", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "ćŠ‚æžœæƒłé©—è­‰äœ ćŒ {name} äč‹é–“ć˜…ç«Żć°ç«ŻćŠ ćŻ†èš­ćźšïŒŒè«‹ć°‡ç•«éąäžŠæ–č昅è‰Č捡搌氍æ–čéƒšæ©Ÿć˜…è‰ČćĄæŻ”ć°äž€äž‹ïŒŒç„¶ćŸŒæŻ”èŒƒćŸ‹ć…©ç”„æ•žć­—ă€‚ćŠ‚æžœć…©é‚Šć””ć»ćˆïŒŒćŻä»„è©Šç”šćŠäž€ć°ćź‰ć…šçąŒă€‚ćȘæœ‰äž€ć°ćź‰ć…šçąŒć»ćˆć°±ćŸ—ă—Žć–‡ă€‚", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "ćŠ‚æžœæƒłé©—è­‰äœ ćŒ {name} äč‹é–“ć˜…ç«Żć°ç«ŻćŠ ćŻ†èš­ćźšïŒŒäœ ćŻä»„ć°ć“äžŠéąć˜…è™ŸçąŒćŒäœąéƒšæ©Ÿć…„éąć˜…è™ŸçąŒă€‚äœąäșŠćŻä»„ç”šäœąéƒšæ©ŸæŽƒäœ ć˜…äșŒç¶­çąŒă€‚", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ćź‰ć…šçąŒèźŠæ›Ž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ćź‰ć…šçąŒć–șéŽæžĄæœŸé–“æ›Žæ–°ç·ŠïŒŒä»„äŸżć•Ÿç”š Signal ćłć°‡æŽšć‡șć˜…ç§éš±ćŠŸèƒœă€‚", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "èŠé©—è­‰ćź‰ć…šçąŒïŒŒè«‹ć°‡è‰ČćĄćŒèŻç”Ąäșșéƒšæ©Ÿć˜…è‰ČćĄæŻ”ć°äž€äž‹ă€‚ćŠ‚æžœć…©é‚Šć””ć»ćˆïŒŒćŻä»„è©Šç”šćŠäž€ć°ćź‰ć…šçąŒă€‚ćȘæœ‰äž€ć°ćź‰ć…šçąŒć»ćˆć°±ćŸ—ă—Žć–‡ă€‚", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "需芁ć諿‰‹ïŒŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "明癜", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "äœ ćŒć°æ–čäș’ç›žć‚łé€èšŠæŻäč‹ćŸŒïŒŒçł»ç”±ć°±æœƒćč«äœ ć»șç«‹äž€ć€‹ćŒäœąć˜…ćź‰ć…šçąŒă€‚", @@ -1267,10 +1359,6 @@ "messageformat": "ç‡ć“æœ€èż‘ć˜…ćȘ’é«”", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "ćŠ‚æžœèŠé©—è­‰äœ ćŒ {name} ć˜…ç«Żć°ç«ŻćŠ ćŻ†äż‚ć’Șćź‰ć…šïŒŒäœ ćŻä»„ć°ć“äžŠéąć˜…è™ŸçąŒćŒäœąéƒšæ©Ÿć…„éąć˜…è™ŸçąŒă€‚äœąäșŠćŻä»„æŽƒäžŠéąć˜…äșŒç¶­çąŒă€‚", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "äœ ć†‡ćŒć‘ąć€‹èŻç”Ąäșșć‚łé€éŽä»»äœ•èšŠæŻă€‚äœ ć“‹ć˜…ćź‰ć…šçąŒæœƒć–șäœ ć“‹é–‹ć§‹é€šèšŠćŸŒć‡șçŸă€‚" }, @@ -1334,17 +1422,17 @@ "messageformat": "è©łçŽ°", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ćˆȘ陀", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ćˆȘé™€èšŠæŻ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "係ć’Ș芁ćˆȘé™€èŠć€©ć‘€ïŒŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "係ć’Ș芁ćˆȘé™€èšŠæŻïŒŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "ć‘ąć€‹èŠć€©æœƒć–șć‘ąéƒšæ©ŸćșŠćˆȘ陀。", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "ć‘ąć€‹èŠć€©ć…„éąć˜…èšŠæŻæœƒć–șć‘ąéƒšæ©ŸćșŠćˆȘ陀。 ćˆȘé™€èšŠæŻäč‹ćŸŒïŒŒäœ ä»ç„¶ćŻä»„æœć°‹ćˆ°ć‘ąć€‹èŠć€©ă€‚", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "é›ąé–‹çŸ€ç”„", @@ -1438,6 +1526,14 @@ "messageformat": "ć…©ć€‹èŠć€©ć˜…èšŠæŻçŽ€éŒ„ć·Č經ć–șćșŠćˆäœ”撗。", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} äż‚ć±Źæ–Œ {conversationTitle} ć˜…ă€‚äœ ć“‹ć…©ć€‹éƒœäż‚ {sharedGroup} ć˜…çŸ€ç”„æˆć“Ąă€‚", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} äż‚ć±Źæ–Œ {conversationTitle} 昅", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ćŒ•ç”šèšŠæŻć˜…çžźćœ–", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "æ‰“ć€šæŹĄ", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "é–‹ć§‹é€šè©±", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ćŠ ć…„é€šè©±", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "曠ç‚șé€šè©±ć…„éąæœ‰ć€Ș〚äșșïŒŒæ‰€ä»„ć€‹ć’Șć·Čç¶“èŒƒć’—ćšéœéŸł", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "通話通矄", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "通話äșș敞ć·Čç¶“æ»żć’—", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "盞機", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "抠慄", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "開構", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "通話äșș敞ć·Čæ»ż", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "盞機ć·Čç¶“ćœç”š", @@ -1621,10 +1725,6 @@ "messageformat": "打開盞機", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "靜音", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "ć·Čç¶“ćœç”šć’—ć€‹ć’Ș", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "é–‹èż”ć€‹ć’Ș", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "戆äș«", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "ç°Ąć ±ć·Čç¶“ćœç”š", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ćœæ­ąç°Ąć ±", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "響鈮", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "ć€‹çŸ€ç”„ć€Șć€§ïŒŒć†‡ćŸ—æ‰“äżŸćƒèˆ‡è€…ă€‚", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "開敟響鈮", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "閂鈮èČ", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "開鈮èČ", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "慶他遞項", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "䜠", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "äœ ć€‹ç›žæ©Ÿé–‚ć’—", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "æȘąèŠ–ćź‰ć…šçąŒ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ć‚łé€èšŠæŻ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "æȘąèŠ–ćź‰ć…šçąŒ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "æ”ć””ćˆ°é›»è©±è™ŸçąŒă€‚è«‹æȘ࿟„搓ç¶Čç”Ąé€Łç·šç„¶ćŸŒć†è©ŠéŽć•Šă€‚", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "䜠ćȘćŻä»„ć–șć‚łé€èšŠæŻćŸŒ 3 ć°æ™‚ć…§ć„—ç”šç·šèŒŻă€‚", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "䜠ćȘćŻä»„ć–șć‚łé€èšŠæŻćŸŒ 24 ć€‹é˜ć…§ć„—ç”šç·šèŒŻă€‚", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "ć‘ąć€‹èšŠæŻć·Č經ćˆȘ陀撗。", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "附件ć€Ș性饯ç€ș攔戰。", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "有ć•Č附件ć€Ș性饯ç€ș攔戰。", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "æ”žć””ćˆ°ææŹŸè©łæƒ…", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ćȘ限 Signal æžŹè©Šç‰ˆ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ç·šèŒŻèšŠæŻćŠŸèƒœćȘ限 Signal æžŹè©Šç‰ˆć˜…ç”šæˆ¶äœżç”šă€‚ćȘ有甚 Signal æœ€æ–°æžŹè©Šç‰ˆć˜…ç”šæˆ¶ć…ˆćŻä»„ç‡ćˆ°äœ ć˜…ç·šèŒŻèšŠæŻă€‚", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ç·šèŒŻèšŠæŻ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ćȘ有甚 Signal æœ€æ–°ç‰ˆæœŹć˜…ç”šæˆ¶ć…ˆćŻä»„ç‡ćˆ°äœ ć˜…ç·šèŒŻèšŠæŻă€‚äœąć“‹æœƒèŠ‹ćˆ°äœ ç·šèŒŻć’—èšŠæŻă€‚", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "æ‰“ć…„ćšŸć˜…èŠ–ćƒé€šè©±...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "打ć‡ș昅èȘžéŸłé€šè©±", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "打ć‡șćŽ»ć˜…èŠ–ćƒé€šè©±", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} æ‰“ç·ŠäżŸäœ ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "é‡æ–°é€Łç·Šç·š...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} 怋äșș}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "èȘžéŸłé€šè©±", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "甐束", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "雱開", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "閂撗ć’Ș", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "開撗ć’Ș", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "鈎èČ開撗", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "鈎èČ閂撗", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "èš­ćźš", @@ -3468,13 +3668,25 @@ "messageformat": "ć…šèžąćč•通話", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ćˆ‡æ›ćšç¶Čæ ŒæȘąèŠ–", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "曎æ”čæȘąèŠ–æ–čćŒ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ćˆ‡æ›ćšç™Œèš€è€…æȘąèŠ–", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "䞀栌栌æȘąèŠ–", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ćŽæŹ„æȘąèŠ–", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "ç›źć‰æŒ”èŹ›è€…", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "æ›Žæ–°ć’—æȘąèŠ–æ–čćŒ", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "退ć‡ș通話", @@ -3576,6 +3788,14 @@ "messageformat": "çąș漚", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ç·šèŒŻć””ćˆ°èšŠæŻ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ć‘ąć€‹èšŠæŻćȘćŻä»„ç·šèŒŻ {max,number} æŹĄă€‚", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "ć””ć„œæ„æ€ïŒŒsgnl:// ć‘ąæąé€Łç”ç”šć””ćˆ°ć–ŽïŒ", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ç”šæˆ¶ćçš±", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "äœ ć˜…ç”šæˆ¶ćçš±ć‡șçŸć•éĄŒïŒŒć””ć†æŒ‡ćźšè‡łäœ ć˜…ćžłæˆ¶ă€‚", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ćˆȘé™€ç”šæˆ¶ćçš±", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ć»șç«‹ç”šæˆ¶ćçš±", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "äșŒç¶­çąŒæˆ–連甐", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "éœ€èŠé‡èš­ç”šæˆ¶ćçš±", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "éœ€èŠé‡èš­ç”šæˆ¶ćçš±é€Łç”", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "戆äș«äœ ć˜…ç”šæˆ¶ćçš±", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ćˆȘé™€ç”šæˆ¶ćçš±", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "ć’ćšć˜…è©±ïŒŒäœ ć˜…ç”šæˆ¶ćçš±ć°±æœƒèą«ç§»é™€ïŒŒè€Œć…¶ä»–ç”šæˆ¶ć°±ćŻä»„æ”žć‘ąć€‹ććšŸç”šă—Žć–‡ă€‚äœ äż‚ć’Șè‚ŻćźšèŠć’ćšïŒŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "ć’ćšć˜…è©±ïŒŒçł»ç”±ć°±æœƒç§»é™€äœ ć˜…ç”šæˆ¶ćçš±ćŒćŸ‹ćœç”šäœ ć˜…äșŒç¶­çąŒćŒé€Łç”ă€‚ć…¶ä»–ç”šæˆ¶ć°±ćŻä»„æ”žă€Œ{username}ă€ć‘ąć€‹ććšŸç”šă—Žć–‡ă€‚äœ äż‚ć’ȘçąșćźšïŒŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "äœ ć°‡æœƒć†‡ćŸ—ć†ćˆ†äș«æˆ–è€…ç€èŠœé™æ™‚ć‹•æ…‹ă—Žć–‡ă€‚äœ æœ€èż‘ćˆ†äș«ć˜…é™æ™‚ć‹•æ…‹æ›Žæ–°éƒœæœƒèą«ćˆȘ陀。", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "èȘžèš€", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "èȘžèš€", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "系由èȘžèš€", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "æœć°‹èȘžèš€", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "æ”ć””ćˆ°ćŒă€Œ{searchTerm}ă€ç›žé—œć˜…æœć°‹ç”æžœ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "èš­ćźš", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "重新打開 Signal ćšŸć„—ç”š", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "芁蜉èȘžèš€ïŒŒéœ€èŠé‡æ–°é–‹éŽć€‹ app。", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "重新開 app", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "æ›Žæ–°ç‰ˆæœŹ {version} ć·Č經掚ć‡ș撗", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "ć„Čć­˜äœ ć˜…èš­ćźšć˜…æ™‚ć€™ć‡șçŸéŒŻèȘ€ă€‚è«‹äœ ć†è©ŠéŽć•Šă€‚", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "èšŠæŻ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "æ›Žć€šæŹŸćŒ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "重蚭", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ćźŒæˆ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ç”šæˆ¶ćçš±ć˜…é€Łç”éĄè‰Č{total,number} ć€‹ć…„éąć˜…çŹŹ {index,number} 怋", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ćŠ‚æžœäœ é‡èš­äșŒç¶­çąŒïŒŒäœ ćźœćź¶ç”šç·Šć˜…äșŒç¶­çąŒćŒé€Łç”ć°±æœƒć€±æ•ˆă€‚", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "é‡èš­ç·Šé€Łç”...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "æœȘèš­ćźšäșŒç¶­çąŒćŒé€Łç”ă€‚è«‹æȘ࿟„äœ ć˜…ç¶Čç”Ąé€Łç·šïŒŒç„¶ćŸŒć†è©Šć€šæŹĄć•Šă€‚", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "èš­ćźšäœ ć˜… Signal ç”šæˆ¶ćçš±", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "ć†æŹĄć‚łé€", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "ć…¶ä»–æ“äœœ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "通話", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "新通話", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "新通話", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "ć…¶ä»–æ“äœœ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "枅陀通話玀錄", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "係ć’Ș芁枅陀通話玀錄", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "ć’ćšć˜…è©±ïŒŒæ‰€æœ‰é€šè©±çŽ€éŒ„ć°±æœƒæ°žäč…ćˆȘ陀", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "æž…è”°æ™’äœą", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "通話玀錄ć·Č經枅陀晒", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ă©’ćšŸç‡ć“æˆ–è€…é–‹ć§‹é€šè©±", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "æœć°‹", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "æ č據æœȘæŽ„äŸ†é›»çŻ©éž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ćˆ‡æ›", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "ć†‡æœ€èż‘ć˜…é€šè©±ă€‚éššæ™‚æ‰“äżŸæœ‹ć‹ć‚Ÿć“ćˆć•Šă€‚", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "憇搌「{query}ă€ç›žé—œć˜…æœć°‹ç”æžœ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "䟆電", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "打ć‡ș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "æœȘ掄䟆電", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "成谷通話", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "ć†‡æœ€èż‘ć˜…ć°è©±ă€‚", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "憇搌「{query}ă€ç›žé—œć˜…æœć°‹ç”æžœ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {打ć‡ș昅èȘžéŸłé€šè©±} other {èȘžéŸłé€šè©±äŸ†é›»}}} Video {{direction, select, Outgoing {打ć‡șćŽ»ć˜…èŠ–ćƒé€šè©±} other {æ‰“ć…„ćšŸć˜…èŠ–ćƒé€šè©±}}} Group {{direction, select, Outgoing {打ć‡șć˜…çŸ€ç”„é€šè©±} other {矀甄通話䟆電}}} other {{direction, select, Outgoing {打ć‡ș昅 通話} other {æ‰“ć…„ćšŸć˜… 通話}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {æœȘæŽ„ć˜…èȘžéŸłé€šè©±} Video {æœȘæŽ„ć˜…èŠ–ćƒé€šè©±} Group {æœȘæŽ„ć˜…çŸ€ç”„é€šè©±} other {æœȘ掄䟆電}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {æœȘæŽ„ć˜…èȘžéŸłé€šè©±} Video {æœȘæŽ„ć˜…èŠ–ćƒé€šè©±} Group {æœȘæŽ„ć˜…çŸ€ç”„é€šè©±} other {æœȘæŽ„ć˜… 通話}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {æ‹’æŽ„ć˜…èȘžéŸłé€šè©±} Video {æ‹’æŽ„ć˜…èŠ–ćƒé€šè©±} Group {æ‹’æŽ„ć˜…çŸ€ç”„é€šè©±} other {æ‹’æŽ„ć˜… 通話}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {ćŠć€–æœ‰ {count,number} 怋äșșæ‰“ç·Šć­—ă€‚}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "æœ€æ–°æ¶ˆæŻ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "æˆ‘ć“‹ćšć’—ć•ČèȘżæ•Žă€äżźćŸ©ć’—䞀ć•Č錯èȘ€ïŒŒćŒćŸ‹ćŠ ćŒ·ć’—çš‹ćŒćŠŸèƒœă€‚ć€šèŹäœ äœżç”š Signal", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "ć‘ąæŹĄæ›Žæ–°æ”č斄撗èȘžéŸłćŒèŠ–ćƒé€šè©±ïŒŒæ–‡ä»¶æ–č靱äșŠéƒœćšć’—䞀ć•ČçŽ°ćŸźæ›Žæ–° ({linkToGithub}ïŒŒć””è©Č晒)。" + "icu:WhatsNew__v6.39--0": { + "messageformat": "è€Œćź¶äœ ćŻä»„ç›ŽæŽ„ć–ș Signal ć…„éąéžæ“‡èȘžèš€ïŒŒć””äœżć†æ”čçł»ç”±èš­ćźšć•ŠïŒˆSignal èš­ćźš > ä»‹éąèš­ćźš > èȘžèš€ïŒ‰ă€‚" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "æˆ‘ć“‹äżźæ”čć’—æ›Žæ–°çŸ€ç”„èł‡æ–™æ™‚éĄŻç€șć˜…é€šçŸ„ćœ–ç€ș ïŒŒäŸ‹ćŠ‚ç•¶æœ‰æ–°æˆć“ĄćŠ ć…„çŸ€ç”„æ™‚ă€‚ć‘ąć•Č朖ç€șæŻ”ä»„ć‰æ›ŽćŠ æž…æ„šæ˜“ç‡ïŒŒæœ€ć•±éŸæ„ç”šă€Œæ·±è‰ČæšĄćŒă€ć˜…äœ ă€‚" + "icu:WhatsNew__v6.39--1": { + "messageformat": "æˆ‘ć“‹æ•Žć„œć’—ć–ș macOS èŁçœźćșŠćŠ ć…„é€šè©±çŸ€ç”„ć—°é™Łé–“äž­æœƒç™Œç”Ÿć˜…ć°‘ć°‘ć»¶éČïŒŒć’ä»„ćŸŒć°±ćŻä»„éżć…æœ‰äșș開會éČćˆ°æŸć‘ąć€‹ćšè—‰ćŁć•Šă€‚" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "æˆ‘ć“‹äżźćŸ©ć’—æœ‰äșșćŠ ć…„æˆ–è€…é›ąé–‹çŸ€ç”„é€šè©±æ™‚ç•«éąæœƒć‡șçŸć˜…éŽæžĄć‹•ç•«ă€‚" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "è€Œćź¶ïŒŒäœ ćȘéœ€èŠă©’äž€äž‹èŠć€©æš™éĄŒć˜…ć€‹äșșæˆ–è€…çŸ€ç”„é ­ćƒïŒŒć°±ćŻä»„ćż«é€Ÿè·łćŽ»èŠć€©èš­ćźšïŒŒä»ČćŻä»„ćłćˆ»ç‡ćˆ°äœ æœȘç‡ć˜…é™æ™‚ć‹•æ…‹ă€‚ć””è©Č晒{linkToGithub}" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/zh-CN/messages.json b/_locales/zh-CN/messages.json index 2042681581..fa97f10b18 100644 --- a/_locales/zh-CN/messages.json +++ b/_locales/zh-CN/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "æ•°æźćș“é”™èŻŻ", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ć‡ș现äș†äž€äžȘæ•°æźćș“é”™èŻŻă€‚æ‚šćŻä»„ć€ćˆ¶é”™èŻŻäżĄæŻćč¶è”çł» Signal æ”ŻæŒć›ąé˜ŸććŠ©ć€„ç†èŻ„é—źéą˜ă€‚ćŠ‚æžœæ‚šéœ€èŠç«‹ćłäœżç”š SignalïŒŒæ‚šćŻä»„ćˆ é™€æ•°æźćč¶é‡æ–°ćŻćŠšă€‚\n\nèŻ·èźżé—źæ­€çœ‘ć€è”çł»æ”ŻæŒć›ąé˜ŸïŒš{link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ćˆ é™€æ‰€æœ‰æ•°æźćč¶é‡ćŻ", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ćˆ é™€æ•°æźćč¶é‡æ–°ćŻćŠš", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "芁氞äč…ćˆ é™€æ‰€æœ‰æ•°æźć—ïŒŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "æ‚šçš„æ‰€æœ‰æ¶ˆæŻèź°ćœ•ć’ŒćȘ’äœ“ć°†äŒšä»Žæ­€èźŸć€‡äž­æ°žäč…ćˆ é™€ă€‚é‡æ–°ć…łè”ćŽïŒŒæ‚šć°†èƒœć€Ÿćœšæ­€èźŸć€‡äžŠäœżç”š Signală€‚æ­€æ“äœœäžäŒšä»Žæ‚šçš„æ‰‹æœșäž­ćˆ é™€ä»»äœ•æ•°æźă€‚", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "æ‚šçš„æ•°æźćș“ç‰ˆæœŹäžŽæ­€ç‰ˆæœŹçš„ Signal 䞍ćŒčé…ă€‚èŻ·çĄźäżæ‚šćœšç””è„‘äžŠæ‰“ćŒ€çš„æ˜Żæœ€æ–°ç‰ˆæœŹçš„ Signal。", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "文件(&F)", @@ -300,6 +316,70 @@ "messageformat": "èŠć€©", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "æ‚šçš„ç”šæˆ·ćć‡ș闼鱘äș†ïŒŒćźƒć·Čäžć†ćˆ†é…ç»™æ‚šçš„èŽŠæˆ·ă€‚æ‚šćŻä»„ć°èŻ•é‡æ–°èźŸçœźïŒŒæˆ–é€‰æ‹©äž€äžȘæ–°ç”šæˆ·ćă€‚", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ç«‹ćˆ»è§Łć†ł", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "悚的äșŒç»Žç ć’Œç”šæˆ·ćé“ŸæŽ„ć‡ș闼鱘äș†ïŒŒćźƒä»Źć·Čç»ć€±æ•ˆă€‚èŻ·ćˆ›ć»ș侀äžȘæ–°é“ŸæŽ„ä»„äŸżćˆ†äș«ç»™ć…¶ä»–ç”šæˆ·ă€‚", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ç«‹ćˆ»è§Łć†ł", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "星ç€ș选éĄč捡", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "隐藏选éĄč捡", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ć‡ș现äș†äž€äžȘé”™èŻŻ", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} æĄæœȘèŻ»", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "ć·Č标äžșæœȘèŻ»", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "èŠć€©", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "é€šèŻ", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "ćŠšæ€", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "èźŸçœź", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "捇çș§ Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "äžȘäșș蔄料", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "èż”ć›ž", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "èż™äș›èŠć€©ć·Čć­˜æĄŁïŒŒä»…ćœ“æ”¶ćˆ°æ–°æ¶ˆæŻæ—¶æ‰äŒšć‡șçŽ°ćœšæ”¶ä»¶çź±äž­ă€‚", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "ä»èŠć‘Œć«", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ä»ç„¶ćŠ ć…„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "ç»§ç»­é€šèŻ", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ćź‰ć…šç æ­Łćœšæ›Žæ–°äž­ă€‚", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "äș†è§Łæ›Žć€š", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "侊侀äžȘ漉慹码", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "例侀äžȘ漉慹码", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ćź‰ć…šç ç‰ˆæœŹïŒŒ{index,number}/{total,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "æ ‡èź°äžșć·ČéȘŒè݁", @@ -663,33 +747,41 @@ "messageformat": "枅陀éȘŒè݁", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "ćŠ‚èŠéȘŒèŻæ‚šäžŽ{name}的端ćŻčç«ŻćŠ ćŻ†ćŠŸèƒœïŒŒèŻ·ć°†äžŠæ–čçš„æ•°ć­—äžŽćŻčæ–čçš„èźŸć€‡èż›èĄŒæŻ”ćŻč。ćŻčæ–čäčŸćŻä»„äœżç”šè‡Șć·±çš„èźŸć€‡æ‰«ææ‚šçš„äșŒç»Žç ă€‚", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "äș†è§Łæ›Žć€š", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "ćŠ‚èŠéȘŒèŻæ‚šäžŽ{name}的端ćŻčç«ŻćŠ ćŻ†ćŠŸèƒœïŒŒèŻ·ć°†äžŠæ–č的è‰Č捡侎ćŻčæ–čçš„èźŸć€‡ćŒč配ć趿ݔćŻčćź‰ć…šç ă€‚ćŠ‚æžœäșŒè€…䞍ćŒčé…ïŒŒèŻ·ć°èŻ•ćŠäž€ćŻč漉慹码。éȘŒèŻä»…éœ€ćŒč配侀ćŻč漉慹码。", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "ćŠ‚èŠéȘŒèŻæ‚šäžŽ{name}的端ćŻčç«ŻćŠ ćŻ†ćŠŸèƒœïŒŒèŻ·ć°†äžŠæ–čçš„æ•°ć­—äžŽćŻčæ–čçš„èźŸć€‡èż›èĄŒæŻ”ćŻč。ćŻčæ–čäčŸćŻä»„äœżç”šè‡Șć·±çš„èźŸć€‡æ‰«ææ‚šçš„äșŒç»Žç ă€‚", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "慳äșŽćź‰ć…šç çš„ć˜æ›Ž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ćź‰ć…šç ć°†ćœšèż‡æžĄæœŸć†…æ›Žæ–°ïŒŒä»„ćŻç”š Signal ćłć°†æŽšć‡șçš„éšç§ćŠŸèƒœă€‚", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "ćŠ‚èŠéȘŒèŻćź‰ć…šç ïŒŒèŻ·ć°†è‰ČćĄäžŽè”çł»äșșçš„èźŸć€‡ćŒčé…ă€‚ćŠ‚æžœäșŒè€…䞍ćŒčé…ïŒŒèŻ·ć°èŻ•ćŠäž€ćŻč漉慹码。éȘŒèŻä»…éœ€ćŒč配侀ćŻč漉慹码。", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "éœ€èŠććŠ©ïŒŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "矄道äș†", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "ćœšæ‚šäžŽćŻčæ–čäș’ć‘æ¶ˆæŻćŽïŒŒçł»ç»Ÿć°†é’ˆćŻčć…¶ç”Ÿæˆäž€äžȘ漉慹码。", @@ -1267,10 +1359,6 @@ "messageformat": "æŸ„çœ‹æœ€èż‘ćȘ’䜓", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "ćŠ‚èŠéȘŒèŻæ‚šäžŽ{name}的端ćŻčç«ŻćŠ ćŻ†ćŠŸèƒœïŒŒèŻ·ć°†äžŠæ–čçš„æ•°ć­—äžŽćŻčæ–čçš„èźŸć€‡èż›èĄŒæŻ”ćŻč。ćŻčæ–čäčŸćŻä»„扫描䞊æ–č的äșŒç»Žç ă€‚", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "æ‚šèż˜æœȘäžŽèŻ„è”çł»äșșæœ‰ä»»äœ•é€šèźŻïŒŒæ‚šçš„ćź‰ć…šä»Łç ć°†äŒšćœšæ‚šćŻčć…¶ć‘é€çŹŹäž€æĄæ¶ˆæŻćŽæ˜Ÿç€ș。" }, @@ -1334,17 +1422,17 @@ "messageformat": "äżĄæŻ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ćˆ é™€", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ćˆ é™€æ¶ˆæŻ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "èŠćˆ é™€èŠć€©ć—ïŒŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "èŠćˆ é™€æ¶ˆæŻć—ïŒŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "æ­€èŠć€©ć°†äŒšćœšæ­€èźŸć€‡äžŠćˆ é™€ă€‚", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "æ­€èŠć€©äž­çš„æ¶ˆæŻć°†äŒšä»Žæ­€èźŸć€‡äžŠćˆ é™€ă€‚ćˆ é™€æ¶ˆæŻćŽïŒŒæ‚šä»ç„¶ćŻä»„æœçŽąæ­€èŠć€©ă€‚", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "çŠ»ćŒ€çŸ€ç»„", @@ -1438,6 +1526,14 @@ "messageformat": "悚䞀äžȘèŠć€©çš„æ¶ˆæŻèź°ćœ•ć·Č搈ćč¶ćˆ°æ­€ć€„。", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} 汞äșŽ{conversationTitle}ă€‚äœ ä»Źć‡æ˜Ż{sharedGroup}çš„æˆć‘˜ă€‚", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} 汞äșŽ{conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ćŒ•ç”šæ¶ˆæŻć›Ÿç‰‡çš„çŒ©ç•„ć›Ÿ", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "重拚", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "ć‘è”·é€šèŻ", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ćŠ ć…„é€šèŻ", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "由äșŽé€šèŻäșșæ•°äŒ—ć€šïŒŒéșŠć…‹éŁŽć·Č静音", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "é€šèŻé€šçŸ„", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "é€šèŻäșș数ć·Čæ»Ą", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "盾æœș", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "抠慄", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "ćŒ€ć§‹", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "é€šèŻäșș数ć·Čæ»Ą", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "æ‘„ćƒć€Žć·Č穁甹", @@ -1621,10 +1725,6 @@ "messageformat": "ćŒ€ćŻæ‘„ćƒć€Ž", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "静音", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "éșŠć…‹éŁŽć·Č穁甹", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "éșŠć…‹éŁŽć–æ¶ˆé™éŸł", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "戆äș«", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "挔ç€șć·Č穁甹", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ćœæ­ąæŒ”ç€ș", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "拚通", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "矀组äșșæ•°èż‡ć€šïŒŒæ— æł•äžŽć‚äžŽäșșé€šèŻă€‚", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "ćŻç”šæ‹šé€š", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "慳闭铃棰", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "ćŒ€ćŻé“ƒćŁ°", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "æ›Žć€šé€‰éĄč", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "悚", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "æ‘„ćƒć€Žć·Č慳闭", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "æŸ„çœ‹ćź‰ć…šç ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "æ¶ˆæŻ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "æŸ„çœ‹ćź‰ć…šç ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "æ— æł•èŽ·ć–ç””èŻć·ç ă€‚èŻ·æŁ€æŸ„æ‚šçš„çœ‘ç»œèżžæŽ„ćč¶é‡èŻ•ă€‚", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "悚ćȘèƒœćœšć‘é€æ­€æ¶ˆæŻçš„ 3 ć°æ—¶ä»„ć†…èż›èĄŒçŒ–èŸ‘ă€‚", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "悚ćȘèƒœćœšć‘é€æ­€æ¶ˆæŻćŽçš„ 24 ć°æ—¶ä»„ć†…èż›èĄŒçŒ–èŸ‘ă€‚", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "æ¶ˆæŻć·Čćˆ é™€ă€‚", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "附件ć€Șć€§è€Œæ— æł•æ˜Ÿç€ș。", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "有äș›é™„ä»¶ç”±äșŽć€Șć€§è€Œæ— æł•æ˜Ÿç€ș。", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "æ— æł•èŽ·ć–ææŹŸèŻŠæƒ…", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "仅限 Signal æ”‹èŻ•ç‰ˆ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "çŒ–èŸ‘æ¶ˆæŻćŠŸèƒœä»…é™ Signal æ”‹èŻ•ç‰ˆç”šæˆ·äœżç”šă€‚ćŠ‚æžœæ‚šçŒ–èŸ‘æ¶ˆæŻïŒŒć…¶ć°†ä»…ćŻč Signal æœ€æ–°æ”‹èŻ•ç‰ˆçš„ç”šæˆ·ćŻè§ă€‚", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "çŒ–èŸ‘æ¶ˆæŻ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ćŠ‚æžœæ‚šçŒ–èŸ‘æ¶ˆæŻïŒŒć…¶ć°†ä»…ćŻčäœżç”šæœ€æ–°ç‰ˆ Signal çš„ç”šæˆ·ćŻè§ă€‚èż™äș›ç”šæˆ·ć°†äŒšçœ‹ćˆ°æ‚šçŒ–èŸ‘äș†æ¶ˆæŻă€‚", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "è§†éą‘æ„ç””â€Š", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "拚ć‡șèŻ­éŸłé€šèŻ", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "拚ć‡șè§†éą‘é€šèŻ", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer}æ­Łćœšć‘Œć«æ‚š", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "é‡æ–°èżžæŽ„â€Š", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} äșș}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "éŸłéą‘é€šèŻ", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "结束", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "çŠ»ćŒ€", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "éșŠć…‹éŁŽć…łé—­", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "éșŠć…‹éŁŽćŒ€ćŻ", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "é“ƒćŁ°ćŒ€ćŻ", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "铃棰慳闭", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "èźŸçœź", @@ -3468,13 +3668,25 @@ "messageformat": "ć…šć±é€šèŻ", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ćˆ‡æąè‡łçœ‘æ Œè§†ć›Ÿ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "曎æ”čè§†ć›Ÿ", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ćˆ‡æąè‡łć‘èš€äșșè§†ć›Ÿ", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "çœ‘æ Œè§†ć›Ÿ", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "䟧èŸčæ è§†ć›Ÿ", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "èŻŽèŻäșșè§†ć›Ÿ", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "è§†ć›Ÿć·Č曎新", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "çŠ»ćŒ€é€šèŻ", @@ -3576,6 +3788,14 @@ "messageformat": "ć„œçš„", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "æ— æł•çŒ–èŸ‘æ¶ˆæŻ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "æ­€æ¶ˆæŻćȘ胜ćș”甚 {max,number} æŹĄçŒ–èŸ‘ă€‚", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "抱歉 sgnl:// é“ŸæŽ„æ— æł•è§ŁæžïŒ", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ç”šæˆ·ć", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "æ‚šçš„ç”šæˆ·ćć‡ș闼鱘äș†ïŒŒćźƒć·Čäžć†ćˆ†é…ç»™æ‚šçš„èŽŠæˆ·ă€‚", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ćˆ é™€ç”šæˆ·ć", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "戛ć»șç”šæˆ·ć", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "äșŒç»Žç æˆ–铟掄", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "ç”šæˆ·ćéœ€èŠé‡çœź", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "ç”šæˆ·ćé“ŸæŽ„éœ€èŠé‡çœź", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "戆äș«æ‚šçš„ç”šæˆ·ć", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ćˆ é™€ç”šæˆ·ć", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "æ‚šçš„ç”šæˆ·ćć°†äŒšèą«ćˆ é™€ïŒŒćč¶ćŻäŸ›ć…¶ä»–ç”šæˆ·é€‰ç”šă€‚æ‚šçĄźćźšèŠćˆ é™€ć—ïŒŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "èż™æ ·ćšć°†äŒšćˆ é™€æ‚šçš„ç”šæˆ·ććč¶äœżæ‚šçš„äșŒç»Žç ć’Œé“ŸæŽ„ć€±æ•ˆă€‚ć…¶ä»–ç”šæˆ·ć°†ćŻä»„ç”łèŻ·äœżç”šâ€œ{username}â€èż™äžȘç”šæˆ·ćă€‚çĄźćźšèŠæ›Žæ”čć—ïŒŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "æ‚šć°†æ— æł•ć†ćˆ†äș«æˆ–æ”è§ˆćŠšæ€ă€‚æ‚šæœ€èż‘ć‘ćžƒçš„ćŠšæ€æ›Žæ–°äčŸć°†äŒšèą«ćˆ é™€ă€‚", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "èŻ­èš€", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "èŻ­èš€", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "çł»ç»ŸèŻ­èš€", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "æœçŽąèŻ­èš€", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "æČĄæœ‰æ‰Ÿćˆ°â€œ{searchTerm}â€çš„ç›žć…łç»“æžœ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "èźŸçœź", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "重搯 Signal 仄ćș”甚曎æ”č", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "曎æ”čèŻ­èš€éœ€èŠé‡ćŻćș”甚。", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "重搯", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "{version} ç‰ˆæœŹæœ‰æ›Žæ–°", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "äżć­˜æ‚šçš„èźŸçœźæ—¶ć‡șé”™ïŒŒèŻ·é‡èŻ•ă€‚", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "æ¶ˆæŻ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "æ›Žć€šéŁŽæ Œ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "é‡çœź", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ćźŒæˆ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ç”šæˆ·ćé“ŸæŽ„éąœè‰Č{index,number}/{total,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ćŠ‚æžœé‡çœźäșŒç»Žç ïŒŒæ‚šçŽ°æœ‰çš„äșŒç»Žç ć’Œé“ŸæŽ„ć°†äŒšć€±æ•ˆă€‚", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "æ­Łćœšé‡çœźé“ŸæŽ„â€Šâ€Š", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "äșŒç»Žç ć’Œé“ŸæŽ„æœȘèźŸçœźă€‚èŻ·æŁ€æŸ„æ‚šçš„äș’è”çœ‘èżžæŽ„ćč¶é‡èŻ•ă€‚", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "èźŸçœźæ‚šçš„ Signal ç”šæˆ·ć", "description": "Title of username onboarding modal" @@ -6577,7 +6865,7 @@ "description": "Body of a dialog displayed on unsupported operating systems" }, "icu:MessageMetadata__edited": { - "messageformat": "ć·Č猖蟑", + "messageformat": "猖蟑", "description": "label for an edited message" }, "icu:EditHistoryMessagesModal__title": { @@ -6592,6 +6880,114 @@ "messageformat": "é‡æ–°ć‘é€", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "æ›Žć€šæ“äœœ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "é€šèŻ", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "æ–°é€šèŻ", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "æ–°é€šèŻ", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "æ›Žć€šæ“äœœ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "æž…é™€é€šèŻèź°ćœ•", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "èŠæž…é™€é€šèŻèź°ćœ•ć—ïŒŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "æ­€æ“äœœć°†æ°žäč…ćˆ é™€æ‰€æœ‰é€šèŻèź°ćœ•", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "枅陀", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "é€šèŻèź°ćœ•ć·Čæž…ç©ș", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "ç‚čć‡»æŸ„çœ‹æˆ–ć‘è”·é€šèŻ", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "æœçŽą", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "筛选æœȘæŽ„é€šèŻ", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ćˆ‡æą", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "æČĄæœ‰æœ€èż‘ć‘Œć«ă€‚ ć‘Œć«æœ‹ć‹ćŒ€ć§‹äș’抚搧。", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "æČĄæœ‰æ‰Ÿćˆ°â€œ{query}â€çš„ç›žć…łç»“æžœ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "杄甔", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "掻甔", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "æœȘ掄", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "çŸ€ç»„é€šèŻ", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "æœ€èż‘æČĄæœ‰ćŻčèŻă€‚", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "æČĄæœ‰æ‰Ÿćˆ°â€œ{query}â€çš„ç›žć…łç»“æžœ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {拚ć‡șèŻ­éŸłé€šèŻ} other {èŻ­éŸłæ„ç””}}} Video {{direction, select, Outgoing {拚ć‡șè§†éą‘é€šèŻ} other {è§†éą‘æ„ç””}}} Group {{direction, select, Outgoing {拚ć‡șçŸ€ç»„é€šèŻ} other {æ‹šć…„çŸ€ç»„é€šèŻ}}} other {{direction, select, Outgoing {ć‘Œć«} other {杄甔}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {æœȘæŽ„èŻ­éŸłæ„ç””} Video {æœȘæŽ„è§†éą‘æ„ç””} Group {æœȘæŽ„çŸ€ç»„é€šèŻ} other {æœȘ掄杄甔}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {æœȘæŽ„èŻ­éŸłé€šèŻ} Video {æœȘæŽ„è§†éą‘é€šèŻ} Group {æœȘæŽ„çŸ€ç»„é€šèŻ} other {æœȘæŽ„é€šèŻ}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {æ‹’æŽ„çš„èŻ­éŸłé€šèŻ} Video {æ‹’æŽ„çš„è§†éą‘é€šèŻ} Group {æ‹’æŽ„çš„çŸ€ç»„é€šèŻ} other {æ‹’æŽ„çš„é€šèŻ}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {ć…¶ä»– {count,number} äșșæ­ŁćœšèŸ“ć…„ă€‚}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "æœ€æ–°æ¶ˆæŻ", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "æˆ‘ä»Źèż›èĄŒäș†ćŠŸèƒœćŸźè°ƒă€æŒæŽžäżźć€ć’Œæ€§èƒœćŒșćŒ–ă€‚æ„Ÿè°ąäœżç”š Signal", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "æ­€æŹĄæ›Žæ–°ćŒ…ć«èŻ­éŸłć’Œè§†éą‘é€šèŻæ–č靱的侀äș›äŒ˜ćŒ–仄揊侀äș›æ–‡æĄŁæ–čéąçš„ć°æ›Žæ–°ă€‚ïŒˆćŻčæ­€æˆ‘ä»ŹèŠæ„Ÿè°ą{linkToGithub}" + "icu:WhatsNew__v6.39--0": { + "messageformat": "çŽ°ćœšæ‚šæ— éœ€æ›Žæ”čçł»ç»ŸèźŸçœźćłćŻćœš Signal 䞭曎æ”迉€é€‰èŻ­èš€ïŒˆSignal èźŸçœź > ć€–è§‚ > èŻ­èš€ïŒ‰ă€‚" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "æˆ‘ä»Źæ›Žæ–°äș†äž€äș›çŸ€ç»„é€šçŸ„ć›Ÿæ ‡ă€‚" + "icu:WhatsNew__v6.39--1": { + "messageformat": "æˆ‘ä»Źäżźć€äș†ćœš macOS çł»ç»ŸäžŠćŠ ć…„é€šèŻć€§ćŽ…æ—¶ć¶ć°”äŒšć‡șçŽ°çŸ­æš‚ć»¶èżŸçš„é—źéą˜ă€‚" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "æˆ‘ä»Źäżźć€äș†ćœ“有äșșćŠ ć…„æˆ–çŠ»ćŒ€çŸ€ç»„é€šèŻæ—¶çš„è§†éą‘ć›Ÿć—çš„èż‡æžĄćŠšç”»ă€‚" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "çŽ°ćœšæ‚šćŻä»„ç‚čć‡»èŠć€©æ ‡ć€Žäž­çš„äžȘäșșè”„æ–™ć€Žćƒæˆ–çŸ€ç»„ć€Žćƒæ„ćż«é€Ÿèźżé—źèŠć€©èźŸçœźæˆ–æŸ„çœ‹èŠć€©äž­æœȘçœ‹èż‡çš„ćŠšæ€ă€‚ćŻčæ­€æˆ‘ä»ŹèŠæ„Ÿè°ą{linkToGithub}" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/zh-HK/messages.json b/_locales/zh-HK/messages.json index 7d3c148129..192d0e71c4 100644 --- a/_locales/zh-HK/messages.json +++ b/_locales/zh-HK/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "èł‡æ–™ćș«éŒŻèȘ€", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ç™Œç”Ÿèł‡æ–™ćș«éŒŻèȘ€ă€‚äœ ćŻä»„è€‡èŁœéŒŻèȘ€äžŠèŻç”Ą Signal æ”ŻæŽäŸ†ćč«ćŠ©è§Łæ±șć•éĄŒă€‚ćŠ‚æžœäœ éœ€èŠç«‹ćłäœżç”š SignalïŒŒćŻä»„ćˆȘé™€äœ çš„èł‡æ–™äžŠé‡æ–°ć•Ÿć‹•ă€‚\n\nèŠèŻç”Ąæ”ŻæŽćœ˜éšŠïŒŒè«‹ć‰ćŸ€ïŒš{link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ćˆȘé™€æ‰€æœ‰èł‡æ–™äžŠé‡æ–°ć•Ÿć‹•", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ćˆȘé™€èł‡æ–™äžŠé‡æ–°ć•Ÿć‹•", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "芁氞äč…ćˆȘé™€æ‰€æœ‰èł‡æ–™ïŒŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "äœ çš„æ‰€æœ‰èšŠæŻæ­·ćČçŽ€éŒ„ć’Œć€šćȘ’é«”ć°‡ćŸžæ­€èŁçœźäž­æ°žäč…ćˆȘé™€ă€‚é‡æ–°é€Łç”ćŸŒïŒŒäœ ć°‡ćŻä»„ćœšæ­€èŁçœźäžŠäœżç”š Signală€‚é€™äžæœƒćˆȘé™€äœ æ‰‹æ©Ÿäž­çš„ä»»äœ•èł‡æ–™ă€‚", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "äœ çš„èł‡æ–™ćș«ç‰ˆæœŹèˆ‡æ­€ Signal çš„ç‰ˆæœŹäžćŒčé…ă€‚è«‹çąșćźšäœ ćœšé›»è…ŠäžŠé–‹ć•Ÿäș†æœ€æ–°ç‰ˆæœŹçš„ Signal。", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "æȘ”æĄˆ (&F)", @@ -300,6 +316,70 @@ "messageformat": "èŠć€©", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "äœ çš„ç”šæˆ¶ćçš±ç™Œç”Ÿć•éĄŒïŒŒäžć†èą«æŒ‡ćźšćˆ°äœ çš„ćžłæˆ¶ă€‚äœ ćŻä»„ć˜—è©Šé‡èš­æˆ–éžæ“‡äž€ć€‹æ–°çš„ă€‚", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ç«‹ćłäżźćŸ©", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "䜠的äșŒç¶­çąŒćŠç”šæˆ¶ćçš±é€Łç”ç™Œç”Ÿć•éĄŒïŒŒć·Čäžć†æœ‰æ•ˆă€‚ć»șç«‹æ–°é€Łç”ä»„èˆ‡ä»–äșș戆äș«ă€‚", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ç«‹ćłäżźćŸ©", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "饯ç€ș遞項暙籀", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "隱藏遞項暙籀", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ç™Œç”ŸéŒŻèȘ€", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} 扇æœȘèź€", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "暙蚘ç‚șæœȘèź€", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "èŠć€©", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "通話", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "é™æ™‚ć‹•æ…‹", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "èš­ćźš", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "曎新 Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "怋äșșèł‡èšŠ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "èż”ć›ž", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "這äș›èŠć€©ć·Č氁歘。ćȘæœ‰æ”¶ćˆ°æ–°èšŠæŻæ™‚ïŒŒæ‰æœƒć‡șçŸćœšæ”¶ä»¶ćŒŁă€‚", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "仍芁通話", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ä»èŠćŠ ć…„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "çčŒçșŒé€šè©±", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ćź‰ć…šçąŒæ­Łćœšæ›Žæ–°äž­ă€‚", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "äș†è§Łæ›Žć€š", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "äžŠäž€ć€‹ćź‰ć…šçąŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "äž‹äž€ć€‹ćź‰ć…šçąŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ćź‰ć…šçąŒç‰ˆæœŹ {total,number} 侭的第 {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "暙蚘ç‚șć·Č驗證", @@ -663,33 +747,41 @@ "messageformat": "枅陀驗證", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "苄芁驗證䜠與 {name} äč‹é–“çš„ç«Żć°ç«ŻćŠ ćŻ†ïŒŒè«‹æŻ”èŒƒäžŠæ–čæ•žć­—èˆ‡ć°æ–čèŁçœźäžŠçš„æ•žć­—æ˜ŻćŠäž€æšŁă€‚ć°æ–čäșŠćŻäœżç”šć…¶èŁçœźæŽƒçž„äœ çš„äșŒç¶­çąŒă€‚", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "äș†è§Łæ›Žć€š", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "苄芁驗證䜠與 {name} äč‹é–“çš„ç«Żć°ç«ŻćŠ ćŻ†ïŒŒè«‹æŻ”ć°äžŠæ–čè‰ČćĄèˆ‡ć°æ–čèŁçœźäžŠçš„è‰ČćĄæ˜ŻćŠćŒčé…ïŒŒä»„ćŠæŻ”èŒƒæ•žć­—ă€‚ćŠ‚æžœé€™äș›ç„Ąæł•ćŒčé…ïŒŒè«‹ć˜—è©ŠćŠäž€ç”„ćź‰ć…šçąŒă€‚ćȘ需芁ćŒč配侀氍。", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "苄芁驗證䜠與 {name} äč‹é–“çš„ç«Żć°ç«ŻćŠ ćŻ†ïŒŒè«‹æŻ”èŒƒäžŠæ–čæ•žć­—èˆ‡ć°æ–čèŁçœźäžŠçš„æ•žć­—æ˜ŻćŠäž€æšŁă€‚ć°æ–čäșŠćŻäœżç”šć…¶èŁçœźæŽƒçž„äœ çš„äșŒç¶­çąŒă€‚", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ćź‰ć…šçąŒèźŠæ›Ž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ćź‰ć…šçąŒæœƒćœšéŽæžĄæœŸé–“é€ČèĄŒæ›Žæ–°ïŒŒä»„ć•Ÿç”š Signal ćłć°‡æŽšć‡șçš„éš±ç§ćŠŸèƒœă€‚", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "èŠé©—è­‰ćź‰ć…šçąŒïŒŒè«‹ć°‡è‰ČćĄèˆ‡èŻç”Ąäșșçš„èŁçœźé…ć°ă€‚ćŠ‚æžœé€™äș›ç„Ąæł•ćŒčé…ïŒŒè«‹ć˜—è©ŠćŠäž€ç”„ćź‰ć…šçąŒă€‚ćȘ需芁ćŒč配侀氍。", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "需芁ćč«ćŠ©ć—ŽïŒŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "我矄道äș†", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "䜠與歀äșșäș€æ›èšŠæŻćŸŒïŒŒæœƒç‚șć…¶ć»șç«‹äž€ć€‹ćź‰ć…šçąŒă€‚", @@ -1267,10 +1359,6 @@ "messageformat": "æŸ„çœ‹æœ€èż‘çš„ć€šćȘ’é«”æȘ”", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "苄芁驗證䜠與 {name} äč‹é–“ç«Żć°ç«ŻćŠ ćŻ†çš„ćź‰ć…šæ€§ïŒŒè«‹æŻ”èŒƒäžŠæ–čæ•žć­—èˆ‡ć°æ–čèŁçœźäžŠçš„æ•žć­—æ˜ŻćŠäž€æšŁă€‚ć°æ–čäșŠćŻæŽƒçž„䞊æ–č的äșŒç¶­çąŒă€‚", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "äœ ć°šæœȘèˆ‡é€™ć€‹èŻç”Ąäșșäș€æ›èšŠæŻă€‚äœ èˆ‡ä»–ć€‘çš„ćź‰ć…šçąŒć°‡æœƒćœšćˆæŹĄé€ć‡șèšŠæŻćŸŒç”Ÿæ•ˆă€‚" }, @@ -1334,17 +1422,17 @@ "messageformat": "èł‡èšŠ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ćˆȘ陀", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ćˆȘé™€èšŠæŻ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "æ˜ŻćŠćˆȘé™€èŠć€©ïŒŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "芁ćˆȘé™€èšŠæŻć—ŽïŒŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "æ­€èŠć€©ć°‡ćŸžæ­€èŁçœźäžŠćˆȘ陀。", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "æ­€èŠć€©äž­çš„èšŠæŻć°‡ćŸžæ­€èŁçœźäžŠćˆȘ陀。 ćˆȘé™€èšŠæŻćŸŒïŒŒäœ ä»ćŻæœć°‹æ­€èŠć€©ă€‚", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "é›ąé–‹çŸ€ç”„", @@ -1438,6 +1526,14 @@ "messageformat": "ć…©ç”„èŠć€©çš„èšŠæŻçŽ€éŒ„ć·Čćœšæ­€è™•ćˆäœ”ă€‚", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} æ˜Żć±Źæ–Œ {conversationTitle}ă€‚äœ ć€‘éƒœæ˜Ż {sharedGroup} çš„æˆć“Ąă€‚", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} æ˜Żć±Źæ–Œ {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ćŒ•ç”šèšŠæŻçš„çžźćœ–", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "重撄電話", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "é–‹ć§‹é€šè©±", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ćŠ ć…„é€šè©±", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "ć› é€šè©±äșșæ•žçœŸć€šè€Œć°‡éș„態鱹靜音", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "䟆電通矄", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "通話äșș敞ć·Čæ»ż", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "盞機", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "抠慄", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "開構", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "通話äșș敞ć·Čæ»ż", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "盞機ć·Č關閉", @@ -1621,10 +1725,6 @@ "messageformat": "é–‹ć•Ÿç›žæ©Ÿ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "靜音", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "éș„態鱹ć·Č關閉", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "ć–æ¶ˆéș„態鱹靜音", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "戆äș«", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "汕ç€șć·Č關閉", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ćœæ­ąć±•ç€ș", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "撄電話", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "矀甄ć€Șć€§ïŒŒç„Ąæł•ç”Šćƒèˆ‡è€…æ‰“é›»è©±ă€‚", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "é–‹ć•Ÿé€šè©±", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "關閉響鈮", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "開敟響鈮", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "æ›Žć€šéžé …", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "䜠", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "䜠的盞機ć·Č關閉", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "æȘąèŠ–ćź‰ć…šçąŒ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "ć‚łé€èšŠæŻ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "æȘąèŠ–ćź‰ć…šçąŒ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ć–ćŸ—äœżç”šè€…ćçš±ć€±æ•—ă€‚æȘ࿟„䜠的ç¶Čè·Żé€ŁæŽ„äžŠé‡è©Šă€‚", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ç·šèŒŻćȘèƒœćœšäœ ć‚łé€æ­€èšŠæŻćŸŒçš„ 3 ć°æ™‚ć…§ć„—ç”šă€‚", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ç·šèŒŻćȘèƒœćœšäœ ć‚łé€æ­€èšŠæŻćŸŒçš„ 24 ć°æ™‚ć…§ć„—ç”šă€‚", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "é€™ć‰‡èšŠæŻć·Čèą«ćˆȘ陀。", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "附件ć€Șć€§ç„Ąæł•éĄŻç€ș。", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "有äș›é™„ä»¶ć€Șć€§è€Œç„Ąæł•éĄŻç€ș。", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ç„Ąæł•æ“·ć–ææŹŸè©łæƒ…", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ćȘ限 Signal æžŹè©Šç‰ˆ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ç·šèŒŻèšŠæŻćƒ…é©ç”šæ–Œ Signal æžŹè©Šç‰ˆç”šæˆ¶ă€‚ćȘæœ‰äœżç”šæœ€æ–° Signal æžŹè©Šç‰ˆçš„ç”šæˆ¶æ‰èƒœçœ‹ćˆ°äœ çš„ç·šèŒŻèšŠæŻă€‚", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ç·šèŒŻèšŠæŻ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ćȘæœ‰äœżç”šæœ€æ–° Signal ç‰ˆæœŹçš„ç”šæˆ¶æ‰èƒœçœ‹ćˆ°äœ çš„ç·šèŒŻèšŠæŻă€‚ä»–ć€‘ć°‡èƒœçœ‹ćˆ°äœ ç·šèŒŻäș†èšŠæŻă€‚", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "䟆電芖蚊通話...", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "撄打èȘžéŸłé€šè©±", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "æ’„ć‡ș芖蚊電話", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ć°‡æ’„é›»è©±ç”Šäœ ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "é‡æ–°é€ŁæŽ„...", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} äșș}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "èȘžéŸłé€šè©±", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "甐束", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "雱開", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "關閉éș„態鱹", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "開敟éș„態鱹", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "開敟響鈮", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "關閉響鈮", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "èš­ćźš", @@ -3468,13 +3668,25 @@ "messageformat": "ć…šèžąćč•通話", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ćˆ‡æ›ćˆ°æ Œć­ç‹€æŽ’ćˆ—èŠ–ćœ–", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "èźŠæ›ŽæȘąèŠ–", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ćˆ‡æ›ćˆ°æšèČć™šèŠ–ćœ–", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ç¶Čæ ŒæȘąèŠ–", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ćŽé‚ŠæŹ„æȘąèŠ–", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "癌蚀äșșæȘąèŠ–", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ć·Č曎新æȘąèŠ–", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "é›ąé–‹é€šè©±", @@ -3576,6 +3788,14 @@ "messageformat": "ć„œçš„", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ç„Ąæł•ç·šèŒŻèšŠæŻ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ćȘ有 {max,number} é …ç·šèŒŻèƒœć„—ç”šćˆ°æ­€èšŠæŻă€‚", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "抱歉è©Č sgnl://link æČ’有任䜕意矩", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "ç”šæˆ¶ćçš±", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "äœ çš„ç”šæˆ¶ćçš±ç™Œç”Ÿć•éĄŒïŒŒäžć†èą«æŒ‡ćźšćˆ°äœ çš„ćžłæˆ¶ă€‚", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ćˆȘé™€äœżç”šè€…ćçš±", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "ć»șç«‹ç”šæˆ¶ćçš±", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "äșŒç¶­çąŒæˆ–連甐", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "éœ€èŠé‡èš­ç”šæˆ¶ćçš±", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "éœ€èŠé‡èš­ç”šæˆ¶ćçš±é€Łç”", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "戆äș«äœ çš„ç”šæˆ¶ćçš±", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ćˆȘé™€äœżç”šè€…ćçš±", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "這氇ćˆȘé™€æ‚šçš„äœżç”šè€…ćçš±ïŒŒé€™ć°‡ćŻèź“ć…¶ä»–äœżç”šè€…äœżç”šă€‚æ‚šçąșćźšć—ŽïŒŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "這氇ćˆȘé™€äœ çš„ç”šæˆ¶ćçš±ćŠćœç”šäœ çš„äșŒç¶­çąŒć’Œé€Łç”ă€‚ă€Œ{username}ă€ć°‡æœƒäŸ›ć…¶ä»–äșșäœżç”šă€‚äœ çąșćźšć—ŽïŒŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "æ‚šć°‡ç„Ąæł•ć†ćˆ†äș«æˆ–ç€èŠœé™æ™‚ć‹•æ…‹ă€‚æ‚šæœ€èż‘ćˆ†äș«çš„é™æ™‚ć‹•æ…‹æ›Žæ–°äčŸć°‡æœƒèą«ćˆȘ陀。", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "èȘžèš€", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "èȘžèš€", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "系由èȘžèš€", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "æœć°‹èȘžèš€", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "æČ’æœ‰çŹŠćˆă€Œ{searchTerm}ă€çš„ç”æžœ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "èš­ćźš", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "重敟 Signal äŸ†ć„—ç”š", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "芁曎æ”čèȘžèš€ïŒŒéœ€èŠé‡æ–°ć•Ÿć‹•æ‡‰ç”šçš‹ćŒă€‚", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "é‡æ–°ć•Ÿć‹•", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "æ›Žæ–°ćˆ°ćŻç”šçš„ {version} ç‰ˆæœŹ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "äżć­˜èš­ćźšæ™‚ć‡ș錯。 è«‹ć†è©Šäž€æŹĄă€‚", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "èšŠæŻ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "æ›Žć€šæŹŸćŒ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "重蚭", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ćźŒæˆ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ç”šæˆ¶ćçš±é€Łç”éĄè‰Č{total,number} 侭的 {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ćŠ‚æžœäœ é‡èš­äșŒç¶­çąŒïŒŒäœ çŸæœ‰çš„äșŒç¶­çąŒć’Œé€Łç”ć°‡æœƒç„Ąæ•ˆă€‚", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "æ­Łćœšé‡èš­é€Łç”...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "æœȘèš­ćźšäșŒç¶­çąŒćŠé€Łç”ă€‚è«‹æȘ࿟„䜠的ç¶Čè·Żé€Łç·šïŒŒç„¶ćŸŒć†è©Šäž€æŹĄă€‚", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "èš­ćźšäœ çš„ Signal ç”šæˆ¶ćçš±", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "é‡æ–°ć‚łé€", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "æ›Žć€šæ“äœœ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "通話", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "新通話", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "新通話", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "æ›Žć€šæ“äœœ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "枅陀通話玀錄", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "èŠæž…é™€é€šè©±çŽ€éŒ„ć—ŽïŒŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "é€™ć°‡æ°žäč…ćˆȘ陀所有通話蚘錄", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "枅陀", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "æˆćŠŸćˆȘ陀通話玀錄", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "點擊仄æȘąèŠ–æˆ–é–‹ć§‹é€šè©±", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "æœć°‹", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "䟝據æœȘæŽ„é€šè©±çŻ©éž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ćˆ‡æ›", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "æČ’æœ‰æœ€èż‘çš„é€šè©±ă€‚è‡Žé›»ç”Šć„œć‹ïŒŒé–‹ć§‹äœżç”šć§ă€‚", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "æČ’æœ‰çŹŠćˆă€Œ{query}ă€çš„ç”æžœ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "䟆電", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "æ’„ć‡ș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "æœȘ掄䟆電", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "矀甄通話", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "æČ’æœ‰æœ€èż‘çš„ć°è©±ă€‚", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "æČ’æœ‰çŹŠćˆă€Œ{query}ă€çš„ç”æžœ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {撄打èȘžéŸłé€šè©±} other {èȘžéŸłé€šè©±äŸ†é›»}}} Video {{direction, select, Outgoing {æ’„ć‡ș芖蚊電話} other {芖蚊電話䟆電}}} Group {{direction, select, Outgoing {æ’„ć‡ș矀甄通話} other {矀甄通話䟆電}}} other {{direction, select, Outgoing {æ’„ć‡ș 通話} other {䟆電}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {æœȘ掄的èȘžéŸłé€šè©±} Video {éŒŻéŽèŠ–èšŠé›»è©±} Group {æœȘ掄矀甄的通話} other {æœȘ掄䟆電}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {æœȘ掄的èȘžéŸłé€šè©±} Video {æœȘ掄的芖蚊電話} Group {æœȘ掄的矀甄通話} other {æœȘ掄 通話}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {拒掄的èȘžéŸłé€šè©±} Video {拒掄的芖蚊通話} Group {拒掄的矀甄通話} other {拒掄 䟆電}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {ć…¶ä»– {count,number} 怋äșșæ­Łćœšæ‰“ć­—ă€‚}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "有甚éșŒæ–°çš„", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "çŽ°ćŸźçš„èȘżæ•Žă€ć•éĄŒäżźćŸ©ć’Œæ•ˆèƒœæ”čć–„ă€‚æ„ŸèŹć„äœäœżç”š Signal", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "æ­€æ›Žæ–°ćŒ…æ‹Źäș†ć°èȘžéŸłć’ŒèŠ–èšŠé€šè©±çš„äž€äș›æ”čé€ČïŒŒä»„ćŠć°‘æ•žæ–‡ä»¶æ›Žæ–°ïŒˆèŹèŹïŒŒ {linkToGithub}ïŒïŒ‰ă€‚" + "icu:WhatsNew__v6.39--0": { + "messageformat": "çŸćœšïŒŒäœ ćŻä»„ćœš Signal 䞭曎æ”č遞擇的èȘžèš€ïŒŒè€Œç„Ąéœ€æ›Žæ”čçł»ç”±èš­ćźšïŒˆSignal èš­ćźš > ä»‹éąèš­ćźš > èȘžèš€ïŒ‰ă€‚" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "æˆ‘ć€‘äżźæ”čäș†çŸ€ç”„æ›Žæ–°ïŒˆäŸ‹ćŠ‚æœ‰æ–°äșșćŠ ć…„çŸ€ç”„ïŒ‰æ™‚éĄŻç€șçš„é€šçŸ„ćœ–ç€ș。這äș›ćœ–ç€șæœ‰ćŠ©æ–Œæé«˜æ˜“èź€æ€§ïŒŒć°€ć…¶é©ćˆäœżç”šă€Œæ·±è‰ČæšĄćŒă€çš„äœ ă€‚" + "icu:WhatsNew__v6.39--1": { + "messageformat": "æˆ‘ć€‘äżźæ­Łäș†ćœš macOS èŁçœźäžŠćŠ ć…„é€šè©±çŸ€ç”„æ™‚ćŻèƒœç™Œç”Ÿçš„çŸ­æš«ć»¶éČ。" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "æˆ‘ć€‘äżźæ­Łäș†æœ‰äșșćŠ ć…„æˆ–é›ąé–‹çŸ€ç”„é€šè©±æ™‚èŠ–èšŠćœ–ćĄŠçš„éŽæžĄć‹•ç•«ă€‚" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "çŸćœšïŒŒäœ ćŻä»„é»žæ“ŠèŠć€©æš™éĄŒäž­çš„ć€‹äșșèł‡æ–™ç›žç‰‡æˆ–çŸ€ç”„é ­ćƒïŒŒä»„ćż«é€Ÿćˆ°é”èŠć€©èš­ćźšæˆ–æŸ„çœ‹è©ČèŠć€©äž­çš„ä»»äœ•é™æ™‚ć‹•æ…‹ă€‚{linkToGithub}ïŒŒèŹèŹäœ ïŒ" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/_locales/zh-Hant/messages.json b/_locales/zh-Hant/messages.json index d0bb0874ff..a66e4695c7 100644 --- a/_locales/zh-Hant/messages.json +++ b/_locales/zh-Hant/messages.json @@ -110,11 +110,27 @@ }, "icu:databaseError": { "messageformat": "èł‡æ–™ćș«éŒŻèȘ€", - "description": "Shown in a popup if the database cannot start up properly" + "description": "Title of a popup if the database cannot start up properly" + }, + "icu:databaseError__detail": { + "messageformat": "ç™Œç”Ÿèł‡æ–™ćș«éŒŻèȘ€ă€‚äœ ćŻä»„è€‡èŁœéŒŻèȘ€äžŠèŻç”Ą Signal æ”ŻæŽäŸ†ćč«ćŠ©è§Łæ±șć•éĄŒă€‚ćŠ‚æžœäœ éœ€èŠç«‹ćłäœżç”š SignalïŒŒćŻä»„ćˆȘé™€äœ çš„èł‡æ–™äžŠé‡æ–°ć•Ÿć‹•ă€‚\n\nèŠèŻç”Ąæ”ŻæŽćœ˜éšŠïŒŒè«‹ć‰ćŸ€ïŒš{link}", + "description": "Description shown in a popup if the database cannot start up properly" }, "icu:deleteAndRestart": { - "messageformat": "ćˆȘé™€æ‰€æœ‰èł‡æ–™äžŠé‡æ–°ć•Ÿć‹•", - "description": "Shown in a popup if the database cannot start up properly; allows user to delete database and restart" + "messageformat": "ćˆȘé™€èł‡æ–™äžŠé‡æ–°ć•Ÿć‹•", + "description": "Text of a button shown in a popup if the database cannot start up properly; allows user to delete all data in their database and restart" + }, + "icu:databaseError__deleteDataConfirmation": { + "messageformat": "芁氞äč…ćˆȘé™€æ‰€æœ‰èł‡æ–™ïŒŸ", + "description": "Header of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__deleteDataConfirmation__detail": { + "messageformat": "äœ çš„æ‰€æœ‰èšŠæŻæ­·ćČçŽ€éŒ„ć’Œć€šćȘ’é«”ć°‡ćŸžæ­€èŁçœźäž­æ°žäč…ćˆȘé™€ă€‚é‡æ–°é€Łç”ćŸŒïŒŒäœ ć°‡ćŻä»„ćœšæ­€èŁçœźäžŠäœżç”š Signală€‚é€™äžæœƒćˆȘé™€äœ æ‰‹æ©Ÿäž­çš„ä»»äœ•èł‡æ–™ă€‚", + "description": "Description of a confirmation popup shown if the database cannot start up properly and the user selects 'delete data and restart'" + }, + "icu:databaseError__startOldVersion": { + "messageformat": "äœ çš„èł‡æ–™ćș«ç‰ˆæœŹèˆ‡æ­€ Signal çš„ç‰ˆæœŹäžćŒčé…ă€‚è«‹çąșćźšäœ ćœšé›»è…ŠäžŠé–‹ć•Ÿäș†æœ€æ–°ç‰ˆæœŹçš„ Signal。", + "description": "Text in a popup shown if the app cannot start because the user started an older version of Signal" }, "icu:mainMenuFile": { "messageformat": "æȘ”æĄˆ (&F)", @@ -300,6 +316,70 @@ "messageformat": "èŠć€©", "description": "Shown as a header for non-pinned conversations in the left pane" }, + "icu:LeftPane--corrupted-username--text": { + "messageformat": "äœ çš„ç”šæˆ¶ćçš±ç™Œç”Ÿć•éĄŒïŒŒäžć†èą«æŒ‡ćźšćˆ°äœ çš„ćžłæˆ¶ă€‚äœ ćŻä»„ć˜—è©Šé‡èš­æˆ–éžæ“‡äž€ć€‹æ–°çš„ă€‚", + "description": "Text of corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username--action-text": { + "messageformat": "ç«‹ćłäżźćŸ©", + "description": "Text of the button in the corrupted username banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--text": { + "messageformat": "䜠的äșŒç¶­çąŒćŠç”šæˆ¶ćçš±é€Łç”ç™Œç”Ÿć•éĄŒïŒŒć·Čäžć†æœ‰æ•ˆă€‚ ć»șç«‹æ–°é€Łç”ä»„èˆ‡ä»–äșș戆äș«ă€‚", + "description": "Text of corrupted username link banner in the left pane" + }, + "icu:LeftPane--corrupted-username-link--action-text": { + "messageformat": "ç«‹ćłäżźćŸ©", + "description": "Text of the button in the corrupted username link banner in the left pane" + }, + "icu:NavTabsToggle__showTabs": { + "messageformat": "饯ç€ș遞項暙籀", + "description": "Show in the left pane when the nav tabs are hidden, shows the nav tabs" + }, + "icu:NavTabsToggle__hideTabs": { + "messageformat": "隱藏遞項暙籀", + "description": "Show in the nav tabs when the nav tabs are visible, hides the nav tabs" + }, + "icu:NavTabs__ItemIconLabel--HasError": { + "messageformat": "ç™Œç”ŸéŒŻèȘ€", + "description": "Nav Tabs > Tab has error > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--UnreadCount": { + "messageformat": "{count,number} 扇æœȘèź€", + "description": "Nav Tabs > Unread badge > Accessibility Text" + }, + "icu:NavTabs__ItemIconLabel--MarkedUnread": { + "messageformat": "暙蚘ç‚șæœȘèź€", + "description": "Nav Tabs > Unread badge > when conversation is marked unread > Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Chats": { + "messageformat": "èŠć€©", + "description": "Nav Tabs > Chats Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Calls": { + "messageformat": "通話", + "description": "Nav Tabs > Calls Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Stories": { + "messageformat": "栱氎", + "description": "Nav Tabs > Stories Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Settings": { + "messageformat": "èš­ćźš", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Update": { + "messageformat": "曎新 Signal", + "description": "Nav Tabs > Settings Button > Label & Accessibility Text" + }, + "icu:NavTabs__ItemLabel--Profile": { + "messageformat": "怋äșșèł‡èšŠ", + "description": "Nav Tabs > Profile Button > Accessibility Text" + }, + "icu:NavSidebar__BackButtonLabel": { + "messageformat": "èż”ć›ž", + "description": "Shown in the sidebar header when on a nested panel within the current sidebar, takes the user back to the previous step or default sidebar state" + }, "icu:archiveHelperText": { "messageformat": "這äș›èŠć€©èš˜éŒ„ć·Čć°ć­˜ïŒŒćƒ…ćœšæ”¶ćˆ°æ–°èšŠæŻæ™‚æ‰æœƒéĄŻç€șćœšæ”¶ä»¶ć€Ÿäž­ă€‚", "description": "Shown at the top of the archived conversations list in the left pane" @@ -576,6 +656,10 @@ "messageformat": "仍芁通話", "description": "Used on a warning dialog to make it clear that it might be risky to call the conversation." }, + "icu:joinAnyway": { + "messageformat": "ä»èŠćŠ ć…„", + "description": "Used on a warning dialog to make it clear that it might be risky to join the call." + }, "icu:continueCall": { "messageformat": "çčŒçșŒé€šè©±", "description": "Used on a warning dialog to make it clear that it might be risky to continue the group call." @@ -637,23 +721,23 @@ }, "icu:SafetyNumberViewer__migration__text": { "messageformat": "ćź‰ć…šè™ŸçąŒæ­Łćœšæ›Žæ–°äž­ă€‚", - "description": "An explanatory note in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) An explanatory note in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__migration__learn_more": { "messageformat": "äș†è§Łæ›Žć€š", - "description": "A link text in SafetyNumberViewer describing the safety number migration process." + "description": "(Deleted 11/01/2023) A link text in SafetyNumberViewer describing the safety number migration process." }, "icu:SafetyNumberViewer__card__prev": { "messageformat": "äžŠäž€ć€‹ćź‰ć…šçąŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__card__next": { "messageformat": "äž‹äž€ć€‹ćź‰ć…šçąŒ", - "description": "An ARIA label for safety number navigation button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number navigation button." }, "icu:SafetyNumberViewer__carousel__dot": { "messageformat": "ćź‰ć…šçąŒç‰ˆæœŹ {total,number} 侭的第 {index,number}", - "description": "An ARIA label for safety number carousel button." + "description": "(Deleted 11/01/2023) An ARIA label for safety number carousel button." }, "icu:SafetyNumberViewer__markAsVerified": { "messageformat": "暙蚘ç‚șć·Č驗證", @@ -663,33 +747,41 @@ "messageformat": "æž…é™€é©—è­‰çąŒ", "description": "Safety number viewer, verification toggle button, when verified, clears verification state" }, + "icu:SafetyNumberViewer__hint": { + "messageformat": "苄芁驗證䜠與 {name} äč‹é–“çš„ç«Żć°ç«ŻćŠ ćŻ†ïŒŒè«‹æŻ”èŒƒäžŠæ–čæ•žć­—èˆ‡ć°æ–čèŁçœźäžŠçš„æ•žć­—æ˜ŻćŠäž€æšŁă€‚ć°æ–čäșŠćŻäœżç”šć…¶èŁçœźæŽƒçž„äœ çš„äșŒç¶­çąŒă€‚", + "description": "Safety number viewer, text of the hint" + }, + "icu:SafetyNumberViewer__learn_more": { + "messageformat": "äș†è§Łæ›Žć€š", + "description": "Text of 'Learn more' button of SafetyNumberViewerModal modal" + }, "icu:SafetyNumberViewer__hint--migration": { "messageformat": "苄芁驗證䜠與 {name} äč‹é–“çš„ç«Żć°ç«ŻćŠ ćŻ†ïŒŒè«‹æŻ”ć°äžŠæ–čè‰ČćĄèˆ‡ć°æ–čèŁçœźäžŠçš„è‰ČćĄæ˜ŻćŠćŒčé…ïŒŒä»„ćŠæŻ”èŒƒæ•žć­—ă€‚ćŠ‚æžœé€™äș›ç„Ąæł•ćŒčé…ïŒŒè«‹ć˜—è©ŠćŠäž€ç”„ćź‰ć…šçąŒă€‚ćȘ需芁ćŒč配侀氍。", - "description": "Safety number viewer, text of the hint during migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint during migration period" }, "icu:SafetyNumberViewer__hint--normal": { "messageformat": "苄芁驗證䜠與 {name} äč‹é–“çš„ç«Żć°ç«ŻćŠ ćŻ†ïŒŒè«‹æŻ”èŒƒäžŠæ–čæ•žć­—èˆ‡ć°æ–čèŁçœźäžŠçš„æ•žć­—æ˜ŻćŠäž€æšŁă€‚ć°æ–čäșŠćŻäœżç”šć…¶èŁçœźæŽƒçž„äœ çš„äșŒç¶­çąŒă€‚", - "description": "Safety number viewer, text of the hint after migration period" + "description": "(Deleted 11/01/2023). Safety number viewer, text of the hint after migration period" }, "icu:SafetyNumberOnboarding__title": { "messageformat": "ćź‰ć…šè™ŸçąŒèźŠæ›Ž", - "description": "Title of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Title of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p1": { "messageformat": "ćź‰ć…šè™ŸçąŒæœƒćœšéŽæžĄæœŸé–“é€ČèĄŒæ›Žæ–°ïŒŒä»„ć•Ÿç”š Signal ćłć°‡æŽšć‡șçš„éš±ç§ćŠŸèƒœă€‚", - "description": "Paragraph 1 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 1 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__p2": { "messageformat": "èŠé©—è­‰ćź‰ć…šçąŒïŒŒè«‹ć°‡è‰ČćĄèˆ‡èŻç”Ąäșșçš„èŁçœźé…ć°ă€‚ćŠ‚æžœé€™äș›ç„Ąæł•ćŒčé…ïŒŒè«‹ć˜—è©ŠćŠäž€ç”„ćź‰ć…šçąŒă€‚ćȘ需芁ćŒč配侀氍。", - "description": "Paragraph 2 of Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Paragraph 2 of Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__help": { "messageformat": "需芁ćč«ćŠ©ć—ŽïŒŸ", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberOnboarding__close": { "messageformat": "æ”¶ćˆ°", - "description": "Text of a secondary button in Safety number onboarding modal" + "description": "(Deleted 11/01/2023) Text of a secondary button in Safety number onboarding modal" }, "icu:SafetyNumberNotReady__body": { "messageformat": "䜠與歀äșșäș€æ›èšŠæŻćŸŒïŒŒæœƒç‚șć…¶ć»șç«‹äž€ć€‹ćź‰ć…šè™ŸçąŒă€‚", @@ -1267,10 +1359,6 @@ "messageformat": "æŸ„çœ‹æœ€èż‘çš„ć€šćȘ’é«”æȘ”", "description": "This is a menu item for viewing all media (images + video) in a conversation, using the imperative case, as in a command." }, - "icu:verifyHelp": { - "messageformat": "苄芁驗證䜠與 {name} äč‹é–“ç«Żć°ç«ŻćŠ ćŻ†çš„ćź‰ć…šæ€§ïŒŒè«‹æŻ”èŒƒäžŠæ–čæ•žć­—èˆ‡ć°æ–čèŁçœźäžŠçš„æ•žć­—æ˜ŻćŠäž€æšŁă€‚ć°æ–čäșŠćŻæŽƒçž„䞊æ–č的äșŒç¶­çąŒă€‚", - "description": "(deleted 07/05/2023)" - }, "icu:theirIdentityUnknown": { "messageformat": "äœ ć°šæœȘèˆ‡é€™ć€‹èŻç”Ąäșșäș€æ›èšŠæŻă€‚äœ èˆ‡ä»–ć€‘çš„ćź‰ć…šçąŒć°‡æœƒćœšćˆæŹĄé€ć‡șèšŠæŻćŸŒç”Ÿæ•ˆă€‚" }, @@ -1334,17 +1422,17 @@ "messageformat": "èł‡èšŠ", "description": "Shown on the drop-down menu for an individual message, takes you to message detail screen" }, - "icu:deleteMessages": { - "messageformat": "ćˆȘ陀", - "description": "Menu item for deleting messages, title case." + "icu:deleteMessagesInConversation": { + "messageformat": "ćˆȘé™€èšŠæŻ", + "description": "Menu item for deleting all messages in a conversation from your device" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__title": { - "messageformat": "æ˜ŻćŠćˆȘé™€èŠć€©ïŒŸ", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Title" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__title": { + "messageformat": "芁ćˆȘé™€èšŠæŻć—ŽïŒŸ", + "description": "Title for confirmation modal to delete all messages in a conversation" }, - "icu:ConversationHeader__DeleteMessagesConfirmation__description": { - "messageformat": "æ­€èŠć€©ć°‡ćŸžæ­€èŁçœźäžŠćˆȘ陀。", - "description": "Conversation Header > Delete Action > Delete Messages Confirmation Modal > Description" + "icu:ConversationHeader__DeleteMessagesInConversationConfirmation__description": { + "messageformat": "æ­€èŠć€©äž­çš„èšŠæŻć°‡ćŸžæ­€èŁçœźäžŠćˆȘ陀。 ćˆȘé™€èšŠæŻćŸŒïŒŒäœ ä»ćŻæœć°‹æ­€èŠć€©ă€‚", + "description": "Description for confirmation modal to delete all messages in a conversation" }, "icu:ConversationHeader__ContextMenu__LeaveGroupAction__title": { "messageformat": "é›ąé–‹ć°è©±çŸ€ç”„", @@ -1438,6 +1526,14 @@ "messageformat": "ć…©ç”„èŠć€©çš„èšŠæŻçŽ€éŒ„ć·Čćœšæ­€è™•ćˆäœ”ă€‚", "description": "Contents of a dialog shown after clicking 'learn more' button on a conversation merge event." }, + "icu:PhoneNumberDiscovery--notification--withSharedGroup": { + "messageformat": "{phoneNumber} æ˜Żć±Źæ–Œ {conversationTitle}ă€‚äœ ć€‘éƒœæ˜Ż {sharedGroup} çš„æˆć“Ąă€‚", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with." + }, + "icu:PhoneNumberDiscovery--notification--noSharedGroup": { + "messageformat": "{phoneNumber} æ˜Żć±Źæ–Œ {conversationTitle}", + "description": "Shown when we've discovered a phone number for a contact you've been communicating with, but you have no shared groups." + }, "icu:quoteThumbnailAlt": { "messageformat": "ćŒ•ç”šèšŠæŻçš„çžźćœ–", "description": "Used in alt tag of thumbnail images inside of an embedded message quote" @@ -1585,10 +1681,6 @@ "messageformat": "重撄電話", "description": "Button to call someone again" }, - "icu:calling__start": { - "messageformat": "é–‹ć§‹é€šè©±", - "description": "Button label in the call lobby for starting a call" - }, "icu:calling__join": { "messageformat": "ćŠ ć…„é€šè©±", "description": "Button label in the call lobby for joining a call" @@ -1601,13 +1693,25 @@ "messageformat": "éș„ć…‹éąšäŸé€šè©±ć€§ć°è€ŒéœéŸł", "description": "Shown in a call lobby toast if there are a lot of people already on the call" }, + "icu:calling__toasts--aria-label": { + "messageformat": "䟆電通矄", + "description": "Aria label for region of toasts shown during a call (for, e.g. reconnecting, person joined, audio device changed notifications)" + }, "icu:calling__call-is-full": { "messageformat": "通話äșș敞ć·Čæ»ż", "description": "Text in the call lobby when you can't join because the call is full" }, - "icu:calling__button--video__label": { - "messageformat": "盞機", - "description": "Label under the video button" + "icu:CallingLobbyJoinButton--join": { + "messageformat": "抠慄", + "description": "Button label in the call lobby for joining a call" + }, + "icu:CallingLobbyJoinButton--start": { + "messageformat": "開構", + "description": "Button label in the call lobby for starting a call" + }, + "icu:CallingLobbyJoinButton--call-full": { + "messageformat": "通話äșș敞ć·Čæ»ż", + "description": "Button in the call lobby when you can't join because the call is full" }, "icu:calling__button--video-disabled": { "messageformat": "盞機ć·Č關閉", @@ -1621,10 +1725,6 @@ "messageformat": "é–‹ć•Ÿç›žæ©Ÿ", "description": "Button tooltip label for turning on the camera" }, - "icu:calling__button--audio__label": { - "messageformat": "éœéŸłć°è©±", - "description": "Label under the audio button" - }, "icu:calling__button--audio-disabled": { "messageformat": "éș„態鱹ć·Č關閉", "description": "Button tooltip label when the microphone is disabled" @@ -1637,10 +1737,6 @@ "messageformat": "éș„態鱹關閉靜音", "description": "Button tooltip label for turning on the microphone" }, - "icu:calling__button--presenting__label": { - "messageformat": "戆äș«", - "description": "Label under the share screen button" - }, "icu:calling__button--presenting-disabled": { "messageformat": "汕ç€șć·Č關閉", "description": "Button tooltip label for when screen sharing is disabled" @@ -1653,10 +1749,6 @@ "messageformat": "ćœæ­ąć±•ç€ș", "description": "Button tooltip label for stopping screen sharing" }, - "icu:calling__button--ring__label": { - "messageformat": "撄電話", - "description": "Label under the ring button" - }, "icu:calling__button--ring__disabled-because-group-is-too-large": { "messageformat": "矀甄ć€Șć€§ïŒŒç„Ąæł•ç”Šćƒèˆ‡è€…æ‰“é›»è©±ă€‚", "description": "Button tooltip label when you can't ring because the group is too large" @@ -1669,6 +1761,26 @@ "messageformat": "é–‹ć•Ÿé€šè©±", "description": "Button tooltip label for turning ringing on" }, + "icu:CallingButton__ring-off": { + "messageformat": "關閉響鈮", + "description": "Button tooltip label for turning ringing off" + }, + "icu:CallingButton--ring-on": { + "messageformat": "開敟響鈮", + "description": "Button tooltip label for turning ringing on" + }, + "icu:CallingButton--more-options": { + "messageformat": "æ›Žć€šéžé …", + "description": "Tooltip label for button in the calling screen that opens a menu with other call actions such as React or Raise Hand." + }, + "icu:CallingRaisedHandsList__Title": { + "messageformat": "{count, plural, one {Raised hands · {count,number} person} other {Raised hands · {count,number} people}}", + "description": "Shown in the call raised hands list to describe how many people have active raised hands" + }, + "icu:CallingReactions--me": { + "messageformat": "䜠", + "description": "Label next to in-call reactions to indicate that the current user sent that reaction." + }, "icu:calling__your-video-is-off": { "messageformat": "䜠的盞機ć·Č關閉", "description": "Label in the calling lobby indicating that your camera is off" @@ -2147,6 +2259,10 @@ "messageformat": "æȘąèŠ–ćź‰ć…šçąŒ", "description": "In conversation details, label for button to view safety number, opens safety number modal" }, + "icu:ConversationDetails__HeaderButton--Message": { + "messageformat": "èšŠæŻ", + "description": "In conversation details, label for button to switch to the conversation view in order to draft a message in that converation" + }, "icu:SafetyNumberNotification__viewSafetyNumber": { "messageformat": "æȘąèŠ–ćź‰ć…šçąŒ", "description": "In conversation, safety number change notification, label for button to view safety number, opens safety number modal" @@ -2235,8 +2351,8 @@ "messageformat": "ć–ćŸ—äœżç”šè€…ćçš±ć€±æ•—ă€‚æȘ࿟„䜠的ç¶Čè·Żé€ŁæŽ„äžŠé‡è©Šă€‚", "description": "Shown if request to Signal servers to find phone number fails" }, - "icu:ToastManager__CannotEditMessage": { - "messageformat": "ç·šèŒŻćȘèƒœćœšäœ ć‚łé€æ­€èšŠæŻćŸŒçš„ 3 ć°æ™‚ć…§ć„—ç”šă€‚", + "icu:ToastManager__CannotEditMessage_24": { + "messageformat": "ç·šèŒŻćȘèƒœćœšäœ ć‚łé€æ­€èšŠæŻćŸŒçš„ 24 ć°æ™‚ć…§ć„—ç”šă€‚", "description": "Error message when you try to send an edit after message becomes too old" }, "icu:startConversation--username-not-found": { @@ -2480,6 +2596,14 @@ "messageformat": "é€™ć‰‡èšŠæŻć·Čèą«ćˆȘ陀", "description": "Shown in a message's bubble when the message has been deleted for everyone." }, + "icu:message--attachmentTooBig--one": { + "messageformat": "附件ć€Șć€§ç„Ąæł•éĄŻç€ș。", + "description": "Shown in a message bubble if no attachments are left on message when too-large attachments are dropped" + }, + "icu:message--attachmentTooBig--multiple": { + "messageformat": "有äș›é™„ä»¶ć€Șć€§è€Œç„Ąæł•éĄŻç€ș。", + "description": "Shown in a message bubble if any attachments are left on message when too-large attachments are dropped" + }, "icu:donation--missing": { "messageformat": "ç„Ąæł•æ“·ć–ææŹŸè©łæƒ…", "description": "Aria label for donation when we can't fetch the details." @@ -3122,10 +3246,18 @@ }, "icu:SendEdit--dialog--title": { "messageformat": "ćȘ限 Signal æžŹè©Šç‰ˆ", - "description": "Title of the modal shown before sending your first edit message" + "description": "(deleted 8/30) Title of the modal shown before sending your first edit message" }, "icu:SendEdit--dialog--body": { "messageformat": "ç·šèŒŻèšŠæŻćƒ…é©ç”šæ–Œ Signal æžŹè©Šç‰ˆç”šæˆ¶ă€‚ćȘæœ‰äœżç”šæœ€æ–° Signal æžŹè©Šç‰ˆçš„ç”šæˆ¶æ‰èƒœçœ‹ćˆ°äœ çš„ç·šèŒŻèšŠæŻă€‚", + "description": "(deleted 8/30) Body text of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--title2": { + "messageformat": "ç·šèŒŻèšŠæŻ", + "description": "Title of the modal shown before sending your first edit message" + }, + "icu:SendEdit--dialog--body2": { + "messageformat": "ćȘæœ‰äœżç”šæœ€æ–° Signal ç‰ˆæœŹçš„ç”šæˆ¶æ‰èƒœçœ‹ćˆ°äœ çš„ç·šèŒŻèšŠæŻă€‚ä»–ć€‘ć°‡èƒœçœ‹ćˆ°äœ ç·šèŒŻäș†èšŠæŻă€‚", "description": "Body text of the modal shown before sending your first edit message" }, "icu:SendFormatting--dialog--title": { @@ -3380,6 +3512,14 @@ "messageformat": "䟆電芖蚊電話 ", "description": "Shown in both the incoming call bar and notification for an incoming video call" }, + "icu:outgoingAudioCall": { + "messageformat": "撄打èȘžéŸłé€šè©±", + "description": "Shown in the timeline for an outgoing voice call" + }, + "icu:outgoingVideoCall": { + "messageformat": "æ’„ć‡ș芖蚊電話", + "description": "Shown in the timeline for an outgoing video call" + }, "icu:incomingGroupCall__ringing-you": { "messageformat": "{ringer} ć°‡æ’„é›»è©±ç”Šäœ ", "description": "Shown in the incoming call bar when someone is ringing you for a group call" @@ -3424,9 +3564,69 @@ "messageformat": "重新撄打 ", "description": "Shown in the call screen when the call is reconnecting due to network issues" }, - "icu:callDuration": { - "messageformat": "Signal {duration}", - "description": "Shown in the call screen to indicate how long the call has been connected" + "icu:CallControls__InfoDisplay--participants": { + "messageformat": "{count, plural, other {{count,number} äșș}}", + "description": "Shown in the call screen and lobby for group calls to specify the number of members in the call or in the group. Count is at always at least 1." + }, + "icu:CallControls__InfoDisplay--audio-call": { + "messageformat": "èȘžéŸłé›»è©±", + "description": "Shown in the call lobby for a direct 1:1 call when the caller's video is disabled, to specify that an audio call will be placed when clicking the Start button." + }, + "icu:CallControls__JoinLeaveButton--hangup-1-1": { + "messageformat": "甐束", + "description": "Title for the hangup button for a direct 1:1 call with only 2 participants." + }, + "icu:CallControls__JoinLeaveButton--hangup-group": { + "messageformat": "雱開", + "description": "Title for the hangup button for a group call." + }, + "icu:CallControls__MutedToast--muted": { + "messageformat": "關閉éș„態鱹", + "description": "Shown in a call when the user mutes their audio input using the Mute toggle button." + }, + "icu:CallControls__MutedToast--unmuted": { + "messageformat": "開敟éș„態鱹", + "description": "Shown in a call when the user is muted and then unmutes their audio input using the Mute toggle button." + }, + "icu:CallControls__RingingToast--ringing-on": { + "messageformat": "開敟響鈮", + "description": "Shown in a group call lobby when call ringing is disabled, then the user enables ringing using the Ringing toggle button." + }, + "icu:CallControls__RingingToast--ringing-off": { + "messageformat": "關閉響鈮", + "description": "Shown in a group call lobby when call ringing is enabled, then the user disables ringing using the Ringing toggle button." + }, + "icu:CallControls__RaiseHandsToast--you": { + "messageformat": "Your hand is raised.", + "description": "Shown in a call when the user raises their hand." + }, + "icu:CallControls__RaiseHandsToast--one": { + "messageformat": "{name} raised a hand.", + "description": "Shown in a call when someone else raises their hand." + }, + "icu:CallControls__RaiseHandsToast--two": { + "messageformat": "{name} and {otherName} raised a hand.", + "description": "Shown in a call when 2 persons raise their hands." + }, + "icu:CallControls__RaiseHandsToast--more": { + "messageformat": "{name}, {otherName}, and {overflowCount,number} more raised a hand.", + "description": "Shown in a call when 3 or more persons raise their hands." + }, + "icu:CallControls__RaiseHands--open-queue": { + "messageformat": "Open queue", + "description": "Link in call raised hands list and in toast shown when someone else raises their hand. Link opens the list of all raised hands." + }, + "icu:CallControls__RaiseHands--lower": { + "messageformat": "Lower", + "description": "Link in call raised hands list and in toast shown when user raises their hand. Link allows user to lower their hand." + }, + "icu:CallControls__MenuItemRaiseHand": { + "messageformat": "Raise Hand", + "description": "Menu item to raise your hand during a call." + }, + "icu:CallControls__MenuItemRaiseHand--lower": { + "messageformat": "Lower Hand", + "description": "Menu item to lower your previously raised hand during a call." }, "icu:callingDeviceSelection__settings": { "messageformat": "èš­ćźš", @@ -3468,13 +3668,25 @@ "messageformat": "ć…šèžąćč•通話", "description": "Title for picture-in-picture toggle" }, - "icu:calling__switch-view--to-grid": { - "messageformat": "ćˆ‡æ›ćˆ°æ Œć­ç‹€æŽ’ćˆ—èŠ–ćœ–", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__change-view": { + "messageformat": "èźŠæ›ŽæȘąèŠ–", + "description": "Tooltip for changing the in-call layout of remote participants in a group call" }, - "icu:calling__switch-view--to-speaker": { - "messageformat": "ćˆ‡æ›ćˆ°æšèČć™šèŠ–ćœ–", - "description": "Title for grid/speaker view toggle when on a call" + "icu:calling__view_mode--paginated": { + "messageformat": "ç¶Čæ ŒæȘąèŠ–", + "description": "Label for option to view participants in a group call in a paginated grid view" + }, + "icu:calling__view_mode--overflow": { + "messageformat": "ćŽé‚ŠæŹ„æȘąèŠ–", + "description": "Label for option to view participants in a group call where videos that don't fit onto the page are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--speaker": { + "messageformat": "癌蚀äșșæȘąèŠ–", + "description": "Label for option to view participants where only the current speaker's video is fully visible and all others are put into a scrollable overflow sidebar" + }, + "icu:calling__view_mode--updated": { + "messageformat": "ć·Č曎新æȘąèŠ–", + "description": "Toast shown whenver the calling view mode is changed (e.g. paginated view -> speaker view)" }, "icu:calling__hangup": { "messageformat": "é›ąé–‹é€šè©±", @@ -3576,6 +3788,14 @@ "messageformat": "ć„œçš„", "description": "Button to dismiss popup dialog when user-initiated task has gone wrong" }, + "icu:MessageMaxEditsModal__Title": { + "messageformat": "ç„Ąæł•ç·šèŒŻèšŠæŻ", + "description": "Title in popup dialog when attempting to edit a message too many times." + }, + "icu:MessageMaxEditsModal__Description": { + "messageformat": "ćȘ有 {max,number} é …ç·šèŒŻèƒœć„—ç”šćˆ°æ­€èšŠæŻă€‚", + "description": "Description text in popup dialog when attempting to edit a message too many times." + }, "icu:unknown-sgnl-link": { "messageformat": "抱歉è©Č sgnl://link æČ’有任䜕意矩", "description": "Shown if you click on a sgnl:// link not currently supported by Desktop" @@ -5252,10 +5472,30 @@ "messageformat": "äœżç”šè€…ćçš±", "description": "Default text for username field" }, + "icu:ProfileEditor--username--corrupted--body": { + "messageformat": "äœ çš„ç”šæˆ¶ćçš±ç™Œç”Ÿć•éĄŒïŒŒäžć†èą«æŒ‡ćźšćˆ°äœ çš„ćžłæˆ¶ă€‚", + "description": "Text of confirmation modal when the username gets corrupted" + }, + "icu:ProfileEditor--username--corrupted--delete-button": { + "messageformat": "ćˆȘé™€äœżç”šè€…ćçš±", + "description": "Button text for deletion of the username in case of corruption" + }, + "icu:ProfileEditor--username--corrupted--create-button": { + "messageformat": "æ–°ć‰”äœżç”šè€…ćçš±", + "description": "Button text for creation of a new username in case of corruption" + }, "icu:ProfileEditor__username-link": { "messageformat": "äșŒç¶­çąŒæˆ–連甐", "description": "Label of a profile editor row that navigates to username link and qr code modal" }, + "icu:ProfileEditor__username__error-icon": { + "messageformat": "éœ€èŠé‡èš­ç”šæˆ¶ćçš±", + "description": "Accessibility title of an icon in profile editor" + }, + "icu:ProfileEditor__username-link__error-icon": { + "messageformat": "éœ€èŠé‡èš­ç”šæˆ¶ćçš±é€Łç”", + "description": "Accessibility title of an icon in profile editor" + }, "icu:ProfileEditor__username-link__tooltip__title": { "messageformat": "戆äș«äœ çš„ç”šæˆ¶ćçš±", "description": "Title of tooltip displayed under 'QR code or link' button for getting username link" @@ -5320,10 +5560,6 @@ "messageformat": "ćˆȘé™€äœżç”šè€…ćçš±", "description": "Shown as aria label for trash icon next to username" }, - "icu:ProfileEditor--username--confirm-delete-body": { - "messageformat": "這氇ćˆȘé™€äœ çš„äœżç”šè€…ćçš±ïŒŒé€™ć°‡ćŻèź“ć…¶ä»–äœżç”šè€…äœżç”šă€‚äœ çąșćźšć—ŽïŒŸ", - "description": "(deleted 07/10/2023) Shown in dialog body if user has saved an empty string to delete their username" - }, "icu:ProfileEditor--username--confirm-delete-body-2": { "messageformat": "這氇ćˆȘé™€äœ çš„ç”šæˆ¶ćçš±ćŠćœç”šäœ çš„äșŒç¶­çąŒć’Œé€Łç”ă€‚ă€Œ{username}ă€ć°‡æœƒäŸ›ć…¶ä»–äșșäœżç”šă€‚äœ çąșćźšć—ŽïŒŸ", "description": "Shown in dialog body if user has saved an empty string to delete their username" @@ -5612,6 +5848,42 @@ "messageformat": "äœ ć°‡ç„Ąæł•ć†ćˆ†äș«æˆ–ç€èŠœé™æ™‚ć‹•æ…‹ă€‚äœ æœ€èż‘ćˆ†äș«çš„é™æ™‚ć‹•æ…‹æ›Žæ–°äčŸć°‡æœƒèą«ćˆȘ陀。", "description": "Confirmation modal body for disabling stories" }, + "icu:Preferences__Language__Label": { + "messageformat": "èȘžèš€éžé …", + "description": "Language setting label" + }, + "icu:Preferences__Language__ModalTitle": { + "messageformat": "èȘžèš€éžé …", + "description": "Language setting modal title" + }, + "icu:Preferences__Language__SystemLanguage": { + "messageformat": "系由èȘžèš€", + "description": "Option for system language" + }, + "icu:Preferences__Language__SearchLanguages": { + "messageformat": "æœć°‹èȘžèš€", + "description": "Placholder for language preference search box" + }, + "icu:Preferences__Language__NoResults": { + "messageformat": "æČ’æœ‰çŹŠćˆă€Œ{searchTerm}ă€çš„ç”æžœ", + "description": "When no results are found for language preference search" + }, + "icu:Preferences__LanguageModal__Set": { + "messageformat": "èš­ćźš", + "description": "Button to set language preference" + }, + "icu:Preferences__LanguageModal__Restart__Title": { + "messageformat": "重敟 Signal äŸ†ć„—ç”š", + "description": "Title for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Description": { + "messageformat": "芁曎æ”čèȘžèš€ïŒŒéœ€èŠé‡æ–°ć•Ÿć‹•æ‡‰ç”šçš‹ćŒă€‚", + "description": "Description for restart Signal modal to apply language changes" + }, + "icu:Preferences__LanguageModal__Restart__Button": { + "messageformat": "é‡æ–°ć•Ÿć‹•", + "description": "Button to restart Signal to apply language changes" + }, "icu:DialogUpdate--version-available": { "messageformat": "æ›Žæ–°ćˆ°ćŻç”šçš„ {version} ç‰ˆæœŹ", "description": "Tooltip for new update available" @@ -5696,6 +5968,10 @@ "messageformat": "äżć­˜èš­ćźšæ™‚ć‡ș錯。 è«‹ć†è©Šäž€æŹĄă€‚", "description": "Shown if there is an error when saving your preferred reaction settings. Should be very rare to see this message." }, + "icu:MediaEditor__input-placeholder": { + "messageformat": "ć‚łé€èšŠæŻ", + "description": "Placeholder for the input in the media editor" + }, "icu:MediaEditor__clock-more-styles": { "messageformat": "æ›Žć€šæŹŸćŒ", "description": "Action button for switching up the clock styles" @@ -6532,6 +6808,10 @@ "messageformat": "重蚭", "description": "Text of button at the bottom of the username link modal" }, + "icu:UsernameLinkModalBody__done": { + "messageformat": "ćźŒæˆ", + "description": "Text of button at the bottom of the username link modal" + }, "icu:UsernameLinkModalBody__color__radio": { "messageformat": "ç”šæˆ¶ćçš±é€Łç”éĄè‰Č{total,number} 侭的 {index,number}", "description": "ARIA label of button for selecting username link color" @@ -6540,6 +6820,14 @@ "messageformat": "ćŠ‚æžœäœ é‡èš­äșŒç¶­çąŒïŒŒäœ çŸæœ‰çš„äșŒç¶­çąŒć’Œé€Łç”ć°‡æœƒç„Ąæ•ˆă€‚", "description": "Text of confirmation modal when resetting the username link" }, + "icu:UsernameLinkModalBody__resetting-link": { + "messageformat": "æ­Łćœšé‡èš­é€Łç”...", + "description": "Text shown when resetting the username link" + }, + "icu:UsernameLinkModalBody__error__text": { + "messageformat": "æœȘèš­ćźšäșŒç¶­çąŒćŠé€Łç”ă€‚è«‹æȘ࿟„䜠的ç¶Čè·Żé€Łç·šïŒŒç„¶ćŸŒć†è©Šäž€æŹĄă€‚", + "description": "Text of the confirmation dialog shown on username link error" + }, "icu:UsernameOnboardingModalBody__title": { "messageformat": "èš­ćźšäœ çš„ Signal ç”šæˆ¶ćçš±", "description": "Title of username onboarding modal" @@ -6592,6 +6880,114 @@ "messageformat": "ć†æŹĄć‚łé€", "description": "Button text for the confirmation dialog shown to user when attempting to resend message edit" }, + "icu:StoriesTab__MoreActionsLabel": { + "messageformat": "æ›Žć€šæ“äœœ", + "description": "Stories Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__HeaderTitle--CallsList": { + "messageformat": "通話", + "description": "Calls Tab > Header > Title > On Calls List screen" + }, + "icu:CallsTab__HeaderTitle--NewCall": { + "messageformat": "新通話", + "description": "Calls Tab > Header > Title > On New Call screen" + }, + "icu:CallsTab__NewCallActionLabel": { + "messageformat": "新通話", + "description": "Calls Tab > New Call Action Button > Accessibility Label" + }, + "icu:CallsTab__MoreActionsLabel": { + "messageformat": "æ›Žć€šæ“äœœ", + "description": "Calls Tab > More Actions Button (opens context menu) > Accessibility Label" + }, + "icu:CallsTab__ClearCallHistoryLabel": { + "messageformat": "枅陀通話玀錄", + "description": "Calls Tab > More Actions Context Menu > Clear Call History Button Label" + }, + "icu:CallsTab__ConfirmClearCallHistory__Title": { + "messageformat": "èŠæž…é™€é€šè©±çŽ€éŒ„ć—ŽïŒŸ", + "description": "Calls Tab > Confirm Clear Call History Dialog > Title" + }, + "icu:CallsTab__ConfirmClearCallHistory__Body": { + "messageformat": "é€™ć°‡æ°žäč…ćˆȘ陀所有通話蚘錄", + "description": "Calls Tab > Confirm Clear Call History Dialog > Body Text" + }, + "icu:CallsTab__ConfirmClearCallHistory__ConfirmButton": { + "messageformat": "枅陀", + "description": "Calls Tab > Confirm Clear Call History Dialog > Confirm Button" + }, + "icu:CallsTab__ToastCallHistoryCleared": { + "messageformat": "æˆćŠŸćˆȘ陀通話玀錄", + "description": "Calls Tab > Clear Call History > Toast" + }, + "icu:CallsTab__EmptyStateText": { + "messageformat": "點擊仄æȘąèŠ–æˆ–é–‹ć§‹é€šè©±", + "description": "Calls Tab > When no call is selected > Empty state > Call to action text" + }, + "icu:CallsList__SearchInputPlaceholder": { + "messageformat": "æœć°‹", + "description": "Calls Tab > Calls List > Search Input > Placeholder" + }, + "icu:CallsList__ToggleFilterByMissedLabel": { + "messageformat": "䟝據æœȘæŽ„é€šè©±çŻ©éž", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility label" + }, + "icu:CallsList__ToggleFilterByMissed__RoleDescription": { + "messageformat": "ćˆ‡æ›", + "description": "Calls Tab > Calls List > Toggle search filter by missed > Accessibility role description ('A toggle button')" + }, + "icu:CallsList__EmptyState--noQuery": { + "messageformat": "æČ’æœ‰æœ€èż‘é€šè©±ă€‚ æ‰Ÿć€‹ć„œć‹èŠć€©ïŒŒé–‹ć§‹äœżç”šć§ă€‚", + "description": "Calls Tab > Calls List > When no results found > With no search query" + }, + "icu:CallsList__EmptyState--hasQuery": { + "messageformat": "æČ’æœ‰çŹŠćˆă€Œ{query}ă€çš„ç”æžœ", + "description": "Calls Tab > Calls List > When no results found > With a search query" + }, + "icu:CallsList__ItemCallInfo--Incoming": { + "messageformat": "䟆電", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was incoming" + }, + "icu:CallsList__ItemCallInfo--Outgoing": { + "messageformat": "æ’„ć‡ș", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was accepted and was outgoing" + }, + "icu:CallsList__ItemCallInfo--Missed": { + "messageformat": "æœȘ掄䟆電", + "description": "Calls Tab > Calls List > Call Item > Call Status > When call was missed" + }, + "icu:CallsList__ItemCallInfo--GroupCall": { + "messageformat": "矀甄通話", + "description": "Calls Tab > Calls List > Call Item > Call Status > When group call is in its default state" + }, + "icu:CallsNewCall__EmptyState--noQuery": { + "messageformat": "æČ’æœ‰æœ€èż‘çš„ć°è©±ă€‚", + "description": "Calls Tab > New Call > Conversations List > When no results found > With no search query" + }, + "icu:CallsNewCall__EmptyState--hasQuery": { + "messageformat": "æČ’æœ‰çŹŠćˆă€Œ{query}ă€çš„ç”æžœ", + "description": "Calls Tab > New Call > Conversations List > When no results found > With a search query" + }, + "icu:CallHistory__Description--Default": { + "messageformat": "{type, select, Audio {{direction, select, Outgoing {撄打èȘžéŸłé€šè©±} other {èȘžéŸłé€šè©±äŸ†é›»}}} Video {{direction, select, Outgoing {æ’„ć‡ș芖蚊電話} other {芖蚊電話䟆電}}} Group {{direction, select, Outgoing {æ’„ć‡ș矀甄通話} other {矀甄通話䟆電}}} other {{direction, select, Outgoing {æ’„ć‡ș電話} other {䟆電}}}}", + "description": "Call History > Short description of call > When call was not missed or declined (generally accepted)" + }, + "icu:CallHistory__Description--Missed": { + "messageformat": "{type, select, Audio {æœȘ掄的èȘžéŸłé€šè©±} Video {éŒŻéŽèŠ–èšŠé›»è©±} Group {æœȘ掄矀甄的通話} other {æœȘ掄䟆電}}", + "description": "Call History > Short description of call > When incoming call was missed" + }, + "icu:CallHistory__Description--Unanswered": { + "messageformat": "{type, select, Audio {æœȘ掄的èȘžéŸłé€šè©±} Video {æœȘ掄的芖蚊電話} Group {æœȘ掄的矀甄通話} other {æœȘ掄 通話}}", + "description": "Call History > Short description of call > When outgoing call was unanswered" + }, + "icu:CallHistory__Description--Declined": { + "messageformat": "{type, select, Audio {拒掄的èȘžéŸłé€šè©±} Video {拒掄的芖蚊通話} Group {拒掄的矀甄通話} other {拒掄 䟆電}}", + "description": "Call History > Short description of call > When call was declined" + }, + "icu:TypingBubble__avatar--overflow-count": { + "messageformat": "{count, plural, other {ć…¶ä»– {count,number} 怋äșșæ­Łćœšæ‰“ć­—ă€‚}}", + "description": "Group chat multiple person typing indicator when space isn't available to show every avatar, this is the count of avatars hidden." + }, "icu:WhatsNew__modal-title": { "messageformat": "有甚éșŒæ–°çš„", "description": "Title for the whats new modal" @@ -6624,10 +7020,22 @@ "messageformat": "çŽ°ćŸźçš„èȘżæ•Žă€ć•éĄŒäżźćŸ©ć’Œæ•ˆèƒœæ”čć–„ă€‚æ„ŸèŹć„äœäœżç”š Signal", "description": "Release notes for releases that only include bug fixes" }, - "icu:WhatsNew__v6.27--0": { - "messageformat": "æ­€æ›Žæ–°ćŒ…æ‹Źäș†ć°èȘžéŸłć’ŒèŠ–èšŠé€šè©±çš„äž€äș›æ”čé€ČïŒŒä»„ćŠć°‘æ•žæ–‡ä»¶æ›Žæ–°ïŒˆèŹèŹïŒŒ {linkToGithub}ïŒïŒ‰ă€‚" + "icu:WhatsNew__v6.39--0": { + "messageformat": "çŸćœšïŒŒäœ ćŻä»„ćœš Signal 䞭曎æ”č遞擇的èȘžèš€ïŒŒè€Œç„Ąéœ€æ›Žæ”čçł»ç”±èš­ćźšïŒˆSignal èš­ćźš > ä»‹éąèš­ćźš > èȘžèš€ïŒ‰ă€‚" }, - "icu:WhatsNew__v6.28--0": { - "messageformat": "æˆ‘ć€‘äżźæ”čäș†çŸ€ç”„æ›Žæ–°ïŒˆäŸ‹ćŠ‚æœ‰æ–°äșșćŠ ć…„çŸ€ç”„ïŒ‰æ™‚éĄŻç€șçš„é€šçŸ„ćœ–ç€ș。這äș›ćœ–ç€șæœ‰ćŠ©æ–Œæé«˜æ˜“èź€æ€§ïŒŒć°€ć…¶é©ćˆäœżç”šă€Œæ·±è‰ČæšĄćŒă€çš„äœ ă€‚" + "icu:WhatsNew__v6.39--1": { + "messageformat": "æˆ‘ć€‘äżźæ­Łäș†ćœš macOS èŁçœźäžŠćŠ ć…„é€šè©±çŸ€ç”„æ™‚ćŻèƒœç™Œç”Ÿçš„çŸ­æš«ć»¶éČ。" + }, + "icu:WhatsNew__v6.41--0": { + "messageformat": "æˆ‘ć€‘äżźæ­Łäș†æœ‰äșșćŠ ć…„æˆ–é›ąé–‹çŸ€ç”„é€šè©±æ™‚èŠ–èšŠćœ–ćĄŠçš„éŽæžĄć‹•ç•«ă€‚" + }, + "icu:WhatsNew__v6.41--1": { + "messageformat": "çŸćœšïŒŒäœ ćŻä»„é»žæ“ŠèŠć€©æš™éĄŒäž­çš„ć€‹äșșèł‡æ–™ç›žç‰‡æˆ–çŸ€ç”„é ­ćƒïŒŒä»„ćż«é€Ÿćˆ°é”èŠć€©èš­ćźšæˆ–æŸ„çœ‹è©ČèŠć€©äž­çš„ä»»äœ•é™æ™‚ć‹•æ…‹ă€‚{linkToGithub}ïŒŒèŹèŹäœ ïŒ" + }, + "icu:WhatsNew__v6.42--0": { + "messageformat": "We fixed a bug that displayed quoted replies to videos as though they were quoted replies to photos, even though every video is really just a sequence of photos if you think about it." + }, + "icu:WhatsNew__v6.42--1": { + "messageformat": "Thanks to {linkToGithub1} and {linkToGithub2} for their help with this release." } } diff --git a/app/SystemTrayService.ts b/app/SystemTrayService.ts index 161cd619d5..74f4dda9e4 100644 --- a/app/SystemTrayService.ts +++ b/app/SystemTrayService.ts @@ -247,6 +247,7 @@ function getIcon(unreadCount: number) { case 'darwin': iconSize = '16'; break; + case 'linux': case 'win32': iconSize = '32'; break; diff --git a/app/crashReports.ts b/app/crashReports.ts index 8ea2d920d8..8146ea3d2f 100644 --- a/app/crashReports.ts +++ b/app/crashReports.ts @@ -117,7 +117,7 @@ export function setup(getLogger: () => LoggerType, forceEnable = false): void { prefix: 'desktop-crash-', }); - logger.info('crashReports: upload complete'); + logger.info(`crashReports: upload complete, ${url}`); clipboard.writeText(url); } finally { await eraseDumps(logger, pendingDumps); diff --git a/app/locale.ts b/app/locale.ts index 59697ea5b0..8c3d74de56 100644 --- a/app/locale.ts +++ b/app/locale.ts @@ -23,14 +23,28 @@ function getLocaleMessages(locale: string): LocaleMessagesType { return JSON.parse(readFileSync(targetFile, 'utf-8')); } +export type LocaleDisplayNames = Record>; + +function getLocaleDisplayNames(): LocaleDisplayNames { + const targetFile = join( + __dirname, + '..', + 'build', + 'locale-display-names.json' + ); + return JSON.parse(readFileSync(targetFile, 'utf-8')); +} + export type LocaleDirection = 'ltr' | 'rtl'; export type LocaleType = { + availableLocales: Array; i18n: LocalizerType; name: string; direction: LocaleDirection; messages: LocaleMessagesType; hourCyclePreference: HourCyclePreference; + localeDisplayNames: LocaleDisplayNames; }; function getLocaleDirection( @@ -65,10 +79,12 @@ function getLocaleDirection( } function finalize( + availableLocales: Array, messages: LocaleMessagesType, backupMessages: LocaleMessagesType, localeName: string, hourCyclePreference: HourCyclePreference, + localeDisplayNames: LocaleDisplayNames, logger: LoggerType ): LocaleType { // We start with english, then overwrite that with anything present in locale @@ -80,11 +96,13 @@ function finalize( logger.info(`locale: Text info direction for ${localeName}: ${direction}`); return { + availableLocales, i18n, name: localeName, direction, messages: finalMessages, hourCyclePreference, + localeDisplayNames, }; } @@ -99,10 +117,12 @@ export function _getAvailableLocales(): Array { export function load({ preferredSystemLocales, + localeOverride, hourCyclePreference, logger, }: { preferredSystemLocales: Array; + localeOverride: string | null; hourCyclePreference: HourCyclePreference; logger: LoggerType; }): LocaleType { @@ -117,10 +137,11 @@ export function load({ const availableLocales = _getAvailableLocales(); logger.info('locale: Supported locales:', availableLocales.join(', ')); - logger.info('locale: Preferred locales: ', preferredSystemLocales.join(', ')); + logger.info('locale: Preferred locales:', preferredSystemLocales.join(', ')); + logger.info('locale: Locale Override:', localeOverride); const matchedLocale = LocaleMatcher.match( - preferredSystemLocales, + localeOverride != null ? [localeOverride] : preferredSystemLocales, availableLocales, 'en', { algorithm: 'best fit' } @@ -130,12 +151,15 @@ export function load({ const matchedLocaleMessages = getLocaleMessages(matchedLocale); const englishMessages = getLocaleMessages('en'); + const languageDisplayNames = getLocaleDisplayNames(); return finalize( + availableLocales, matchedLocaleMessages, englishMessages, matchedLocale, hourCyclePreference, + languageDisplayNames, logger ); } diff --git a/app/main.ts b/app/main.ts index e7febdd547..0abe11a88f 100644 --- a/app/main.ts +++ b/app/main.ts @@ -100,15 +100,6 @@ import { createTemplate } from './menu'; import { installFileHandler, installWebHandler } from './protocol_filter'; import OS from '../ts/util/os/osMain'; import { isProduction } from '../ts/util/version'; -import { - isSgnlHref, - isCaptchaHref, - isSignalHttpsLink, - parseSgnlHref, - parseCaptchaHref, - parseSignalHttpsLink, - rewriteSignalHrefsIfNecessary, -} from '../ts/util/sgnlHref'; import { clearTimeoutIfNecessary } from '../ts/util/clearTimeoutIfNecessary'; import { toggleMaximizedBrowserWindow } from '../ts/util/toggleMaximizedBrowserWindow'; import { ChallengeMainHandler } from '../ts/main/challengeMain'; @@ -123,6 +114,9 @@ import { load as loadLocale } from './locale'; import type { LoggerType } from '../ts/types/Logging'; import { HourCyclePreference } from '../ts/types/I18N'; +import { DBVersionFromFutureError } from '../ts/sql/migrations'; +import type { ParsedSignalRoute } from '../ts/util/signalRoutes'; +import { parseSignalRoute } from '../ts/util/signalRoutes'; const STICKER_CREATOR_PARTITION = 'sticker-creator'; @@ -149,6 +143,7 @@ const consoleLogger = createBufferedConsoleLogger(); // These will be set after app fires the 'ready' event let logger: LoggerType | undefined; let preferredSystemLocales: Array | undefined; +let localeOverride: string | null | undefined; let resolvedTranslationsLocale: LocaleType | undefined; let settingsChannel: SettingsChannel | undefined; @@ -194,7 +189,11 @@ const defaultWebPrefs = { getEnvironment() !== Environment.Production || !isProduction(app.getVersion()), spellcheck: false, - enableBlinkFeatures: 'CSSPseudoDir,CSSLogical', + // https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/platform/runtime_enabled_features.json5 + enableBlinkFeatures: [ + 'CSSPseudoDir', // status=experimental, needed for RTL (ex: :dir(rtl)) + 'CSSLogical', // status=experimental, needed for RTL (ex: margin-inline-start) + ].join(','), }; const DISABLE_GPU = @@ -265,18 +264,10 @@ if (!process.mas) { return; } - const incomingCaptchaHref = getIncomingCaptchaHref(argv); - if (incomingCaptchaHref) { - const { captcha } = parseCaptchaHref(incomingCaptchaHref, getLogger()); - challengeHandler.handleCaptcha(captcha); - return true; + const route = maybeGetIncomingSignalRoute(argv); + if (route != null) { + handleSignalRoute(route); } - // Are they trying to open a sgnl:// href? - const incomingHref = getIncomingHref(argv); - if (incomingHref) { - handleSgnlHref(incomingHref); - } - // Handled return true; }); } @@ -315,30 +306,32 @@ type GetThemeSettingOptionsType = Readonly<{ async function getThemeSetting({ ephemeralOnly = false, }: GetThemeSettingOptionsType = {}): Promise { + let result: unknown; + const fastValue = ephemeralConfig.get('theme-setting'); if (fastValue !== undefined) { getLogger().info('got fast theme-setting value', fastValue); - return fastValue as ThemeSettingType; - } - - if (ephemeralOnly) { + result = fastValue; + } else if (ephemeralOnly) { return 'system'; - } + } else { + const json = await sql.sqlCall('getItemById', 'theme-setting'); - const json = await sql.sqlCall('getItemById', 'theme-setting'); + result = json?.value; + } // Default to `system` if setting doesn't exist or is invalid - const setting: unknown = json?.value; - const slowValue = - setting === 'light' || setting === 'dark' || setting === 'system' - ? setting + const validatedResult = + result === 'light' || result === 'dark' || result === 'system' + ? result : 'system'; - ephemeralConfig.set('theme-setting', slowValue); + if (fastValue !== validatedResult) { + ephemeralConfig.set('theme-setting', validatedResult); + getLogger().info('got slow theme-setting value', result); + } - getLogger().info('got slow theme-setting value', slowValue); - - return slowValue; + return validatedResult; } async function getResolvedThemeSetting( @@ -367,6 +360,26 @@ async function getBackgroundColor( throw missingCaseError(theme); } +async function getLocaleOverrideSetting(): Promise { + const fastValue = ephemeralConfig.get('localeOverride'); + // eslint-disable-next-line eqeqeq -- Checking for null explicitly + if (typeof fastValue === 'string' || fastValue === null) { + getLogger().info('got fast localeOverride setting', fastValue); + return fastValue; + } + + const json = await sql.sqlCall('getItemById', 'localeOverride'); + + // Default to `null` if setting doesn't exist yet + const slowValue = typeof json?.value === 'string' ? json.value : null; + + ephemeralConfig.set('localeOverride', slowValue); + + getLogger().info('got slow localeOverride setting', slowValue); + + return slowValue; +} + let systemTrayService: SystemTrayService | undefined; const systemTraySettingCache = new SystemTraySettingCache( sql, @@ -419,6 +432,13 @@ function getPreferredSystemLocales(): Array { return preferredSystemLocales; } +function getLocaleOverride(): string | null { + if (typeof localeOverride === 'undefined') { + throw new Error('getLocaleOverride: Locale not yet initialized!'); + } + return localeOverride; +} + function getResolvedMessagesLocale(): LocaleType { if (!resolvedTranslationsLocale) { throw new Error('getResolvedMessagesLocale: Locale not yet initialized!'); @@ -468,23 +488,21 @@ async function handleUrl(rawTarget: string) { return; } - const target = rewriteSignalHrefsIfNecessary(rawTarget); + const signalRoute = parseSignalRoute(rawTarget); + + // We only want to specially handle urls that aren't requesting the dev server + if (signalRoute != null) { + handleSignalRoute(signalRoute); + return; + } const { protocol, hostname } = parsedUrl; const isDevServer = process.env.SIGNAL_ENABLE_HTTP && hostname === 'localhost'; - // We only want to specially handle urls that aren't requesting the dev server - if ( - isSgnlHref(target, getLogger()) || - isSignalHttpsLink(target, getLogger()) - ) { - handleSgnlHref(target); - return; - } if ((protocol === 'http:' || protocol === 'https:') && !isDevServer) { try { - await shell.openExternal(target); + await shell.openExternal(rawTarget); } catch (error) { getLogger().error(`Failed to open url: ${Errors.toLogFormat(error)}`); } @@ -525,7 +543,7 @@ function handleCommonWindowEvents( const focusInterval = setInterval(setWindowFocus, 10000); window.on('closed', () => clearInterval(focusInterval)); - // Works only for mainWindow because it has `enablePreferredSizeMode` + // Works only for mainWindow and settings because they have `enablePreferredSizeMode` let lastZoomFactor = window.webContents.getZoomFactor(); const onZoomChanged = () => { if ( @@ -541,15 +559,38 @@ function handleCommonWindowEvents( return; } - drop( - settingsChannel?.invokeCallbackInMainWindow('persistZoomFactor', [ - zoomFactor, - ]) - ); - lastZoomFactor = zoomFactor; + if (!mainWindow) { + return; + } + + if (window === mainWindow) { + drop( + settingsChannel?.invokeCallbackInMainWindow('persistZoomFactor', [ + zoomFactor, + ]) + ); + } else { + mainWindow.webContents.setZoomFactor(zoomFactor); + } }; - window.webContents.on('preferred-size-changed', onZoomChanged); + window.on('show', () => { + // Install handler here after we init zoomFactor otherwise an initial + // preferred-size-changed event emits with an undesired zoomFactor. + window.webContents.on('preferred-size-changed', onZoomChanged); + }); + + // Workaround to apply zoomFactor because webPreferences does not handle it + // https://github.com/electron/electron/issues/10572 + // But main window emits ready-to-show before window.Events is available + // so set main window zoom in background.ts + if (window !== mainWindow) { + window.once('ready-to-show', async () => { + const zoomFactor = + (await settingsChannel?.getSettingFromMainWindow('zoomFactor')) ?? 1; + window.webContents.setZoomFactor(zoomFactor); + }); + } nativeThemeNotifier.addWindow(window); @@ -751,8 +792,9 @@ async function createWindow() { } const startInTray = + isTestEnvironment(getEnvironment()) || (await systemTraySettingCache.get()) === - SystemTraySetting.MinimizeToAndStartInSystemTray; + SystemTraySetting.MinimizeToAndStartInSystemTray; const visibleOnAnyScreen = some(screen.getAllDisplays(), display => { if ( @@ -790,7 +832,9 @@ async function createWindow() { setupSpellChecker( mainWindow, getPreferredSystemLocales(), - getResolvedMessagesLocale().i18n + getLocaleOverride(), + getResolvedMessagesLocale().i18n, + getLogger() ); if (!startInTray && windowConfig && windowConfig.maximized) { mainWindow.maximize(); @@ -946,6 +990,7 @@ async function createWindow() { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. + getLogger().info('main window closed event'); mainWindow = undefined; if (settingsChannel) { settingsChannel.setMainWindow(mainWindow); @@ -956,11 +1001,13 @@ async function createWindow() { }); mainWindow.on('enter-full-screen', () => { + getLogger().info('mainWindow enter-full-screen event'); if (mainWindow) { mainWindow.webContents.send('full-screen-change', true); } }); mainWindow.on('leave-full-screen', () => { + getLogger().info('mainWindow leave-full-screen event'); if (mainWindow) { mainWindow.webContents.send('full-screen-change', false); } @@ -976,6 +1023,8 @@ async function createWindow() { return; } + mainWindow.webContents.send('ci:event', 'db-initialized', {}); + const shouldShowWindow = !app.getLoginItemSettings().wasOpenedAsHidden && !startInTray; @@ -1093,9 +1142,9 @@ async function readyForUpdates() { isReadyForUpdates = true; // First, install requested sticker pack - const incomingHref = getIncomingHref(process.argv); + const incomingHref = maybeGetIncomingSignalRoute(process.argv); if (incomingHref) { - handleSgnlHref(incomingHref); + handleSignalRoute(incomingHref); } // Second, start checking for app updates @@ -1315,6 +1364,7 @@ async function showSettingsWindow() { contextIsolation: true, preload: join(__dirname, '../bundles/settings/preload.js'), nativeWindowOpen: true, + enablePreferredSizeMode: true, }, }; @@ -1371,13 +1421,28 @@ async function openArtCreator() { let debugLogWindow: BrowserWindow | undefined; async function showDebugLogWindow() { if (debugLogWindow) { - debugLogWindow.show(); + doShowDebugLogWindow(); return; } + function doShowDebugLogWindow() { + if (debugLogWindow) { + // Electron has [a macOS bug][0] that causes parent windows to become unresponsive + // if it's fullscreen and opens a fullscreen child window. Until that's fixed, we + // only set the parent on MacOS is if the mainWindow is not fullscreen + // [0]: https://github.com/electron/electron/issues/32374 + if (OS.isMacOS() && mainWindow?.isFullScreen()) { + debugLogWindow.setParentWindow(null); + } else { + debugLogWindow.setParentWindow(mainWindow ?? null); + } + debugLogWindow.show(); + } + } + const titleBarOverlay = await getTitleBarOverlay(); - const options = { + const options: Electron.BrowserWindowConstructorOptions = { width: 700, height: 500, resizable: false, @@ -1394,14 +1459,8 @@ async function showDebugLogWindow() { sandbox: true, contextIsolation: true, preload: join(__dirname, '../bundles/debuglog/preload.js'), - nativeWindowOpen: true, }, parent: mainWindow, - // Electron has [a macOS bug][0] that causes parent windows to become unresponsive if - // it's fullscreen and opens a fullscreen child window. Until that's fixed, we - // prevent the child window from being fullscreenable, which sidesteps the problem. - // [0]: https://github.com/electron/electron/issues/32374 - fullscreenable: !OS.isMacOS(), }; debugLogWindow = new BrowserWindow(options); @@ -1414,7 +1473,7 @@ async function showDebugLogWindow() { debugLogWindow.once('ready-to-show', () => { if (debugLogWindow) { - debugLogWindow.show(); + doShowDebugLogWindow(); // Electron sometimes puts the window in a strange spot until it's shown. debugLogWindow.center(); @@ -1548,6 +1607,7 @@ async function initializeSQL( // `sql.sqlCall` will throw an uninitialized error instead of waiting for // init to finish. await sql.initialize({ + appVersion: app.getVersion(), configDir: userDataPath, key, logger: getLogger(), @@ -1581,28 +1641,72 @@ const onDatabaseError = async (error: string) => { } mainWindow = undefined; + const { i18n } = getResolvedMessagesLocale(); + + let deleteAllDataButtonIndex: number | undefined; + let messageDetail: string; + + const buttons = [i18n('icu:copyErrorAndQuit')]; + const copyErrorAndQuitButtonIndex = 0; + const SIGNAL_SUPPORT_LINK = 'https://support.signal.org/error'; + + if (error.includes(DBVersionFromFutureError.name)) { + // If the DB version is too new, the user likely opened an older version of Signal, + // and they would almost never want to delete their data as a result, so we don't show + // that option + messageDetail = i18n('icu:databaseError__startOldVersion'); + } else { + // Otherwise, this is some other kind of DB error, let's give them the option to + // delete. + messageDetail = i18n('icu:databaseError__detail', { + link: SIGNAL_SUPPORT_LINK, + }); + + buttons.push(i18n('icu:deleteAndRestart')); + deleteAllDataButtonIndex = 1; + } + const buttonIndex = dialog.showMessageBoxSync({ - buttons: [ - getResolvedMessagesLocale().i18n('icu:deleteAndRestart'), - getResolvedMessagesLocale().i18n('icu:copyErrorAndQuit'), - ], - defaultId: 1, - cancelId: 1, - detail: redactAll(error), - message: getResolvedMessagesLocale().i18n('icu:databaseError'), + buttons, + defaultId: copyErrorAndQuitButtonIndex, + cancelId: copyErrorAndQuitButtonIndex, + message: i18n('icu:databaseError'), + detail: messageDetail, noLink: true, type: 'error', }); - if (buttonIndex === 1) { + if (buttonIndex === copyErrorAndQuitButtonIndex) { 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(); + } else if ( + typeof deleteAllDataButtonIndex === 'number' && + buttonIndex === deleteAllDataButtonIndex + ) { + const confirmationButtons = [ + i18n('icu:cancel'), + i18n('icu:deleteAndRestart'), + ]; + const cancelButtonIndex = 0; + const confirmDeleteAllDataButtonIndex = 1; + const confirmationButtonIndex = dialog.showMessageBoxSync({ + buttons: confirmationButtons, + defaultId: cancelButtonIndex, + cancelId: cancelButtonIndex, + message: i18n('icu:databaseError__deleteDataConfirmation'), + detail: i18n('icu:databaseError__deleteDataConfirmation__detail'), + noLink: true, + type: 'warning', + }); + + if (confirmationButtonIndex === confirmDeleteAllDataButtonIndex) { + getLogger().error('onDatabaseError: Deleting all data'); + await sql.removeDB(); + userConfig.remove(); + getLogger().error( + 'onDatabaseError: Requesting immediate restart after quit' + ); + app.relaunch(); + } } getLogger().error('onDatabaseError: Quitting application'); @@ -1713,11 +1817,15 @@ app.on('ready', async () => { // Write buffered information into newly created logger. consoleLogger.writeBufferInto(logger); + sqlInitPromise = initializeSQL(userDataPath); + if (!resolvedTranslationsLocale) { preferredSystemLocales = resolveCanonicalLocales( loadPreferredSystemLocales() ); + localeOverride = await getLocaleOverrideSetting(); + const hourCyclePreference = getHourCyclePreference(); logger.info(`app.ready: hour cycle preference: ${hourCyclePreference}`); @@ -1728,13 +1836,12 @@ app.on('ready', async () => { ); resolvedTranslationsLocale = loadLocale({ preferredSystemLocales, + localeOverride, hourCyclePreference, logger: getLogger(), }); } - sqlInitPromise = initializeSQL(userDataPath); - // First run: configure Signal to minimize to tray. Additionally, on Windows // enable auto-start with start-in-tray so that starting from a Desktop icon // would still show the window. @@ -2055,16 +2162,42 @@ async function requestShutdown() { } } -app.on('before-quit', () => { +function getWindowDebugInfo() { + const windows = BrowserWindow.getAllWindows(); + + return { + windowCount: windows.length, + mainWindowExists: windows.some(win => win === mainWindow), + mainWindowIsFullScreen: mainWindow?.isFullScreen(), + }; +} + +app.on('before-quit', e => { getLogger().info('before-quit event', { readyForShutdown: windowState.readyForShutdown(), shouldQuit: windowState.shouldQuit(), + hasEventBeenPrevented: e.defaultPrevented, + ...getWindowDebugInfo(), }); systemTrayService?.markShouldQuit(); windowState.markShouldQuit(); }); +app.on('will-quit', e => { + getLogger().info('will-quit event', { + hasEventBeenPrevented: e.defaultPrevented, + ...getWindowDebugInfo(), + }); +}); + +app.on('quit', e => { + getLogger().info('quit event', { + hasEventBeenPrevented: e.defaultPrevented, + ...getWindowDebugInfo(), + }); +}); + // Quit when all windows are closed. app.on('window-all-closed', () => { getLogger().info('main process handling window-all-closed'); @@ -2113,24 +2246,29 @@ app.on('will-finish-launching', () => { // https://stackoverflow.com/a/43949291 app.on('open-url', (event, incomingHref) => { event.preventDefault(); - - if (isCaptchaHref(incomingHref, getLogger())) { - const { captcha } = parseCaptchaHref(incomingHref, getLogger()); - challengeHandler.handleCaptcha(captcha); - - // Show window after handling captcha - showWindow(); - - return; + const route = parseSignalRoute(incomingHref); + if (route != null) { + handleSignalRoute(route); } - - handleSgnlHref(incomingHref); }); }); -ipc.on('set-badge-count', (_event: Electron.Event, count: number) => { - app.badgeCount = count; -}); +ipc.on( + 'set-badge', + (_event: Electron.Event, badge: number | 'marked-unread') => { + if (badge === 'marked-unread') { + if (process.platform === 'darwin') { + // Will show a ● on macOS when undefined + app.setBadgeCount(undefined); + } else { + // All other OS's need a number + app.setBadgeCount(1); + } + } else { + app.setBadgeCount(badge); + } + } +); ipc.on('remove-setup-menu-items', () => { setupMenu(); @@ -2298,10 +2436,12 @@ ipc.on('get-config', async event => { const parsed = rendererConfigSchema.safeParse({ name: packageJson.productName, + availableLocales: getResolvedMessagesLocale().availableLocales, resolvedTranslationsLocale: getResolvedMessagesLocale().name, resolvedTranslationsLocaleDirection: getResolvedMessagesLocale().direction, hourCyclePreference: getResolvedMessagesLocale().hourCyclePreference, preferredSystemLocales: getPreferredSystemLocales(), + localeOverride: getLocaleOverride(), version: app.getVersion(), buildCreation: config.get('buildCreation'), buildExpiration: config.get('buildExpiration'), @@ -2369,6 +2509,12 @@ ipc.on('locale-data', event => { event.returnValue = getResolvedMessagesLocale().messages; }); +// Ingested in preload.js via a sendSync call +ipc.on('locale-display-names', event => { + // eslint-disable-next-line no-param-reassign + event.returnValue = getResolvedMessagesLocale().localeDisplayNames; +}); + // TODO DESKTOP-5241 ipc.on('OS.getHasCustomTitleBar', event => { // eslint-disable-next-line no-param-reassign @@ -2389,7 +2535,8 @@ ipc.handle( process.versions.node, app.getVersion(), os.version(), - userAgent + userAgent, + OS.getLinuxName() ); } ); @@ -2421,78 +2568,71 @@ ipc.on('preferences-changed', () => { } }); -function getIncomingHref(argv: Array) { - return argv.find(arg => isSgnlHref(arg, getLogger())); +function maybeGetIncomingSignalRoute(argv: Array) { + for (const arg of argv) { + const route = parseSignalRoute(arg); + if (route != null) { + return route; + } + } + return null; } -function getIncomingCaptchaHref(argv: Array) { - return argv.find(arg => isCaptchaHref(arg, getLogger())); -} +function handleSignalRoute(route: ParsedSignalRoute) { + const log = getLogger(); -function handleSgnlHref(incomingHref: string) { - let command; - let args; - let hash; - - if (isSgnlHref(incomingHref, getLogger())) { - ({ command, args, hash } = parseSgnlHref(incomingHref, getLogger())); - } else if (isSignalHttpsLink(incomingHref, getLogger())) { - ({ command, args, hash } = parseSignalHttpsLink(incomingHref, getLogger())); + if (mainWindow == null || !mainWindow.webContents) { + log.error('handleSignalRoute: mainWindow is null or missing webContents'); + return; } - if (mainWindow && mainWindow.webContents) { - if (command === 'addstickers') { - getLogger().info('Opening sticker pack from sgnl protocol link'); - const packId = args?.get('pack_id'); - const packKeyHex = args?.get('pack_key'); - const packKey = packKeyHex - ? Buffer.from(packKeyHex, 'hex').toString('base64') - : ''; - mainWindow.webContents.send('show-sticker-pack', { packId, packKey }); - } else if (command === 'art-auth') { - const token = args?.get('token'); - const pubKeyBase64 = args?.get('pub_key'); + log.info('handleSignalRoute: Matched signal route:', route.key); - mainWindow.webContents.send('authorize-art-creator', { - token, - pubKeyBase64, - }); - } else if (command === 'signal.group' && hash) { - getLogger().info('Showing group from sgnl protocol link'); - mainWindow.webContents.send('show-group-via-link', { hash }); - } else if (command === 'signal.me' && hash) { - getLogger().info('Showing conversation from sgnl protocol link'); - mainWindow.webContents.send('show-conversation-via-signal.me', { hash }); - } else if ( - command === 'show-conversation' && - args && - args.get('conversationId') - ) { - getLogger().info('Showing conversation from notification'); - mainWindow.webContents.send('show-conversation-via-notification', { - conversationId: args.get('conversationId'), - messageId: args.get('messageId'), - storyId: args.get('storyId'), - }); - } else if ( - command === 'start-call-lobby' && - args && - args.get('conversationId') - ) { - getLogger().info('Starting call lobby from notification'); - mainWindow.webContents.send('start-call-lobby', { - conversationId: args.get('conversationId'), - }); - } else if (command === 'show-window') { - mainWindow.webContents.send('show-window'); - } else if (command === 'set-is-presenting') { - mainWindow.webContents.send('set-is-presenting'); - } else { - getLogger().info('Showing warning that we cannot process link'); - mainWindow.webContents.send('unknown-sgnl-link'); - } + if (route.key === 'artAddStickers') { + mainWindow.webContents.send('show-sticker-pack', { + packId: route.args.packId, + packKey: Buffer.from(route.args.packKey, 'hex').toString('base64'), + }); + } else if (route.key === 'artAuth') { + mainWindow.webContents.send('authorize-art-creator', { + token: route.args.token, + pubKeyBase64: route.args.pubKey, + }); + } else if (route.key === 'groupInvites') { + mainWindow.webContents.send('show-group-via-link', { + value: route.args.inviteCode, + }); + } else if (route.key === 'contactByPhoneNumber') { + mainWindow.webContents.send('show-conversation-via-signal.me', { + kind: 'phoneNumber', + value: route.args.phoneNumber, + }); + } else if (route.key === 'contactByEncryptedUsername') { + mainWindow.webContents.send('show-conversation-via-signal.me', { + kind: 'encryptedUsername', + value: route.args.encryptedUsername, + }); + } else if (route.key === 'showConversation') { + mainWindow.webContents.send('show-conversation-via-notification', { + conversationId: route.args.conversationId, + messageId: route.args.messageId, + storyId: route.args.storyId, + }); + } else if (route.key === 'startCallLobby') { + mainWindow.webContents.send('start-call-lobby', { + conversationId: route.args.conversationId, + }); + } else if (route.key === 'showWindow') { + mainWindow.webContents.send('show-window'); + } else if (route.key === 'setIsPresenting') { + mainWindow.webContents.send('set-is-presenting'); + } else if (route.key === 'captcha') { + challengeHandler.handleCaptcha(route.args.captchaId); + // Show window after handling captcha + showWindow(); } else { - getLogger().error('Unhandled sgnl link'); + log.info('handleSignalRoute: Unknown signal route:', route.key); + mainWindow.webContents.send('unknown-sgnl-link'); } } @@ -2553,6 +2693,15 @@ async function ensureFilePermissions(onlyFiles?: Array) { getLogger().info(`Finish ensuring permissions in ${Date.now() - start}ms`); } +ipc.handle('get-media-access-status', async (_event, value) => { + // This function is not supported on Linux + if (!systemPreferences.getMediaAccessStatus) { + return undefined; + } + + return systemPreferences.getMediaAccessStatus(value); +}); + ipc.handle('get-auto-launch', async () => { return app.getLoginItemSettings(await getDefaultLoginItemSettings()) .openAtLogin; @@ -2601,13 +2750,16 @@ ipc.handle('show-save-dialog', async (_event, { defaultPath }) => { return { canceled: false, filePath: finalFilePath }; }); -ipc.handle('getScreenCaptureSources', async () => { - return desktopCapturer.getSources({ - fetchWindowIcons: true, - thumbnailSize: { height: 102, width: 184 }, - types: ['window', 'screen'], - }); -}); +ipc.handle( + 'getScreenCaptureSources', + async (_event, types: Array<'screen' | 'window'> = ['screen', 'window']) => { + return desktopCapturer.getSources({ + fetchWindowIcons: true, + thumbnailSize: { height: 102, width: 184 }, + types, + }); + } +); ipc.handle('executeMenuRole', async ({ sender }, untypedRole) => { const role = untypedRole as MenuItemConstructorOptions['role']; @@ -2788,6 +2940,10 @@ async function showStickerCreatorWindow() { } if (isTestEnvironment(getEnvironment())) { + ipc.handle('ci:test-electron:debug', async (_event, info) => { + process.stdout.write(`ci:test-electron:debug=${JSON.stringify(info)}\n`); + }); + ipc.handle('ci:test-electron:done', async (_event, info) => { if (!process.env.TEST_QUIT_ON_COMPLETE) { return; diff --git a/app/protocol_filter.ts b/app/protocol_filter.ts index 200d1ab097..afb903aae6 100644 --- a/app/protocol_filter.ts +++ b/app/protocol_filter.ts @@ -42,9 +42,8 @@ export function _urlToPath( : decoded.slice(options?.isWindows ? 8 : 7); const withoutQuerystring = _eliminateAllAfterCharacter(withoutScheme, '?'); - const withoutHash = _eliminateAllAfterCharacter(withoutQuerystring, '#'); - return withoutHash; + return withoutQuerystring; } function _createFileHandler({ diff --git a/app/renderWindowsToast.tsx b/app/renderWindowsToast.tsx index 70faa46abb..b48d0fa515 100644 --- a/app/renderWindowsToast.tsx +++ b/app/renderWindowsToast.tsx @@ -8,6 +8,12 @@ import type { WindowsNotificationData } from '../ts/services/notifications'; import { NotificationType } from '../ts/services/notifications'; import { missingCaseError } from '../ts/util/missingCaseError'; +import { + setIsPresentingRoute, + showConversationRoute, + showWindowRoute, + startCallLobbyRoute, +} from '../ts/util/signalRoutes'; function pathToUri(path: string) { return `file:///${encodeURI(path.replace(/\\/g, '/'))}`; @@ -51,21 +57,19 @@ export function renderWindowsToast({ // 1) this maps to the notify() function in services/notifications.ts // 2) this also maps to the url-handling in main.ts if (type === NotificationType.Message || type === NotificationType.Reaction) { - launch = new URL('sgnl://show-conversation'); - launch.searchParams.set('conversationId', conversationId); - if (messageId) { - launch.searchParams.set('messageId', messageId); - } - if (storyId) { - launch.searchParams.set('storyId', storyId); - } + launch = showConversationRoute.toAppUrl({ + conversationId, + messageId: messageId ?? null, + storyId: storyId ?? null, + }); } else if (type === NotificationType.IncomingGroupCall) { - launch = new URL(`sgnl://start-call-lobby`); - launch.searchParams.set('conversationId', conversationId); + launch = startCallLobbyRoute.toAppUrl({ + conversationId, + }); } else if (type === NotificationType.IncomingCall) { - launch = new URL('sgnl://show-window'); + launch = showWindowRoute.toAppUrl({}); } else if (type === NotificationType.IsPresenting) { - launch = new URL('sgnl://set-is-presenting'); + launch = setIsPresentingRoute.toAppUrl({}); } else { throw missingCaseError(type); } diff --git a/app/spell_check.ts b/app/spell_check.ts index cd4d6f943c..bb80e8e96a 100644 --- a/app/spell_check.ts +++ b/app/spell_check.ts @@ -11,6 +11,7 @@ import { maybeParseUrl } from '../ts/util/url'; import type { MenuListType } from '../ts/types/menu'; import type { LocalizerType } from '../ts/types/Util'; import { strictAssert } from '../ts/util/assert'; +import type { LoggerType } from '../ts/types/Logging'; export const FAKE_DEFAULT_LOCALE = 'en-x-ignore'; // -x- is an extension space for attaching other metadata to the locale @@ -55,16 +56,35 @@ export function getLanguages( export const setup = ( browserWindow: BrowserWindow, preferredSystemLocales: ReadonlyArray, - i18n: LocalizerType + localeOverride: string | null, + i18n: LocalizerType, + logger: LoggerType ): void => { const { session } = browserWindow.webContents; + + session.on('spellcheck-dictionary-download-begin', (_event, lang) => { + logger.info('spellcheck: dictionary download begin:', lang); + }); + session.on('spellcheck-dictionary-download-failure', (_event, lang) => { + logger.error('spellcheck: dictionary download failure:', lang); + }); + session.on('spellcheck-dictionary-download-success', (_event, lang) => { + logger.info('spellcheck: dictionary download success:', lang); + }); + session.on('spellcheck-dictionary-initialized', (_event, lang) => { + logger.info('spellcheck: dictionary initialized:', lang); + }); + + // Locale override should be combined with other preferences rather than + // replace them entirely. + const combinedLocales = + localeOverride != null + ? [localeOverride, ...preferredSystemLocales] + : preferredSystemLocales; + const availableLocales = session.availableSpellCheckerLanguages; - const languages = getLanguages( - preferredSystemLocales, - availableLocales, - 'en' - ); - console.log('spellcheck: user locales:', preferredSystemLocales); + const languages = getLanguages(combinedLocales, availableLocales, 'en'); + console.log('spellcheck: user locales:', combinedLocales); console.log( 'spellcheck: available spellchecker languages:', availableLocales diff --git a/build/entitlements.mac.inherit.plist b/build/entitlements.mac.inherit.plist index 89669a38c4..714fc60854 100644 --- a/build/entitlements.mac.inherit.plist +++ b/build/entitlements.mac.inherit.plist @@ -5,7 +5,7 @@ - + com.apple.security.cs.allow-jit diff --git a/build/entitlements.mas.inherit.plist b/build/entitlements.mas.inherit.plist index 89669a38c4..714fc60854 100644 --- a/build/entitlements.mas.inherit.plist +++ b/build/entitlements.mas.inherit.plist @@ -5,7 +5,7 @@ - + com.apple.security.cs.allow-jit diff --git a/build/locale-display-names.json b/build/locale-display-names.json new file mode 100644 index 0000000000..55287e23c9 --- /dev/null +++ b/build/locale-display-names.json @@ -0,0 +1,4762 @@ +{ + "en": { + "af-ZA": "Afrikaans", + "ar": "Arabic", + "az-AZ": "Azerbaijani", + "bg-BG": "Bulgarian", + "bn-BD": "Bangla", + "bs-BA": "Bosnian", + "ca": "Catalan", + "cs": "Czech", + "da": "Danish", + "de": "German", + "el": "Greek", + "en": "English", + "es": "Spanish", + "et-EE": "Estonian", + "eu": "Basque", + "fa-IR": "Persian", + "fi": "Finnish", + "fr": "French", + "ga-IE": "Irish", + "gl-ES": "Galician", + "gu-IN": "Gujarati", + "he": "Hebrew", + "hi-IN": "Hindi", + "hr-HR": "Croatian", + "hu": "Hungarian", + "id": "Indonesian", + "it": "Italian", + "ja": "Japanese", + "ka-GE": "Georgian", + "kk-KZ": "Kazakh", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Korean", + "ky-KG": "Kyrgyz", + "lt-LT": "Lithuanian", + "lv-LV": "Latvian", + "mk-MK": "Macedonian", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Malay", + "my": "Burmese", + "nb": "Norwegian BokmĂ„l", + "nl": "Dutch", + "pa-IN": "Punjabi", + "pl": "Polish", + "pt-BR": "Brazilian Portuguese", + "pt-PT": "European Portuguese", + "ro-RO": "Romanian", + "ru": "Russian", + "sk-SK": "Slovak", + "sl-SI": "Slovenian", + "sq-AL": "Albanian", + "sr": "Serbian", + "sv": "Swedish", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "Filipino", + "tr": "Turkish", + "ug": "Uyghur", + "uk-UA": "Ukrainian", + "ur": "Urdu", + "vi": "Vietnamese", + "yue": "Cantonese", + "zh-CN": "Chinese (China)", + "zh-HK": "Chinese (Hong Kong)", + "zh-Hant": "Traditional Chinese" + }, + "af-ZA": { + "af-ZA": "Afrikaans", + "ar": "Arabies", + "az-AZ": "Azerbeidjans", + "bg-BG": "Bulgaars", + "bn-BD": "Bengaals", + "bs-BA": "Bosnies", + "ca": "Katalaans", + "cs": "Tsjeggies", + "da": "Deens", + "de": "Duits", + "el": "Grieks", + "en": "Engels", + "es": "Spaans", + "et-EE": "Estnies", + "eu": "Baskies", + "fa-IR": "Persies", + "fi": "Fins", + "fr": "Frans", + "ga-IE": "Iers", + "gl-ES": "Galisies", + "gu-IN": "Goedjarati", + "he": "Hebreeus", + "hi-IN": "Hindi", + "hr-HR": "Kroaties", + "hu": "Hongaars", + "id": "Indonesies", + "it": "Italiaans", + "ja": "Japannees", + "ka-GE": "Georgies", + "kk-KZ": "Kazaks", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Koreaans", + "ky-KG": "Kirgisies", + "lt-LT": "Litaus", + "lv-LV": "Letties", + "mk-MK": "Masedonies", + "ml-IN": "Malabaars", + "mr-IN": "Marathi", + "ms": "Maleis", + "my": "Birmaans", + "nb": "Boeknoors", + "nl": "Nederlands", + "pa-IN": "Pandjabi", + "pl": "Pools", + "pt-BR": "Portugees (BrasiliĂ«)", + "pt-PT": "Portugees (Portugal)", + "ro-RO": "Roemeens", + "ru": "Russies", + "sk-SK": "Slowaaks", + "sl-SI": "Sloweens", + "sq-AL": "Albanees", + "sr": "Serwies", + "sv": "Sweeds", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Teloegoe", + "th": "Thai", + "tl-PH": "Filippyns", + "tr": "Turks", + "ug": "Uighur", + "uk-UA": "OekraĂŻens", + "ur": "Oerdoe", + "vi": "ViĂ«tnamees", + "yue": "Kantonees", + "zh-CN": "Chinees (China)", + "zh-HK": "Chinees (Hongkong)", + "zh-Hant": "Chinees (Tradisioneel)" + }, + "ar": { + "af-ZA": "Ű§Ù„ŰŁÙŰ±ÙŠÙ‚Ű§Ù†ÙŠŰ©", + "ar": "Ű§Ù„ŰčŰ±ŰšÙŠŰ©", + "az-AZ": "Ű§Ù„ŰŁŰ°Ű±ŰšÙŠŰŹŰ§Ù†ÙŠŰ©", + "bg-BG": "Ű§Ù„ŰšÙ„ŰșŰ§Ű±ÙŠŰ©", + "bn-BD": "Ű§Ù„ŰšÙ†ŰșŰ§Ù„ÙŠŰ©", + "bs-BA": "Ű§Ù„ŰšÙˆŰłÙ†ÙŠŰ©", + "ca": "Ű§Ù„ÙƒŰȘŰ§Ù„ÙˆÙ†ÙŠŰ©", + "cs": "Ű§Ù„ŰȘŰŽÙŠÙƒÙŠŰ©", + "da": "Ű§Ù„ŰŻŰ§Ù†Ù…Ű±ÙƒÙŠŰ©", + "de": "Ű§Ù„ŰŁÙ„Ù…Ű§Ù†ÙŠŰ©", + "el": "Ű§Ù„ÙŠÙˆÙ†Ű§Ù†ÙŠŰ©", + "en": "Ű§Ù„Ű„Ù†ŰŹÙ„ÙŠŰČÙŠŰ©", + "es": "Ű§Ù„Ű„ŰłŰšŰ§Ù†ÙŠŰ©", + "et-EE": "Ű§Ù„Ű„ŰłŰȘÙˆÙ†ÙŠŰ©", + "eu": "Ű§Ù„ŰšŰ§ŰłÙƒÙŠŰ©", + "fa-IR": "Ű§Ù„ÙŰ§Ű±ŰłÙŠŰ©", + "fi": "Ű§Ù„ÙÙ†Ù„Ù†ŰŻÙŠŰ©", + "fr": "Ű§Ù„ÙŰ±Ù†ŰłÙŠŰ©", + "ga-IE": "Ű§Ù„ŰŁÙŠŰ±Ù„Ù†ŰŻÙŠŰ©", + "gl-ES": "Ű§Ù„ŰŹŰ§Ù„ÙŠÙƒÙŠŰ©", + "gu-IN": "Ű§Ù„ŰșÙˆŰŹŰ§Ű±Ű§ŰȘÙŠŰ©", + "he": "Ű§Ù„ŰčŰšŰ±ÙŠŰ©", + "hi-IN": "Ű§Ù„Ù‡Ù†ŰŻÙŠŰ©", + "hr-HR": "Ű§Ù„ÙƒŰ±ÙˆŰ§ŰȘÙŠŰ©", + "hu": "Ű§Ù„Ù‡Ù†ŰșŰ§Ű±ÙŠŰ©", + "id": "Ű§Ù„Ű„Ù†ŰŻÙˆÙ†ÙŠŰłÙŠŰ©", + "it": "Ű§Ù„Ű„ÙŠŰ·Ű§Ù„ÙŠŰ©", + "ja": "Ű§Ù„ÙŠŰ§ŰšŰ§Ù†ÙŠŰ©", + "ka-GE": "Ű§Ù„ŰŹÙˆŰ±ŰŹÙŠŰ©", + "kk-KZ": "Ű§Ù„ÙƒŰ§ŰČۧ۟۳ŰȘŰ§Ù†ÙŠŰ©", + "km-KH": "Ű§Ù„ŰźÙ…ÙŠŰ±ÙŠŰ©", + "kn-IN": "Ű§Ù„ÙƒÙ†Ű§ŰŻÙŠŰ©", + "ko": "Ű§Ù„ÙƒÙˆŰ±ÙŠŰ©", + "ky-KG": "Ű§Ù„Ù‚ÙŠŰ±ŰșيŰČÙŠŰ©", + "lt-LT": "Ű§Ù„Ù„ÙŠŰȘÙˆŰ§Ù†ÙŠŰ©", + "lv-LV": "Ű§Ù„Ù„Ű§ŰȘÙÙŠŰ©", + "mk-MK": "Ű§Ù„Ù…Ù‚ŰŻÙˆÙ†ÙŠŰ©", + "ml-IN": "Ű§Ù„Ù…Ű§Ù„Ű§ÙŠŰ§Ù„Ű§Ù…ÙŠŰ©", + "mr-IN": "Ű§Ù„Ù…Ű§Ű±Ű§Ű«ÙŠŰ©", + "ms": "Ű§Ù„Ù…Ű§Ù„ÙŠŰČÙŠŰ©", + "my": "Ű§Ù„ŰšÙˆŰ±Ù…ÙŠŰ©", + "nb": "Ű§Ù„Ù†Ű±ÙˆÙŠŰŹÙŠŰ© ŰšÙˆÙƒÙ…Ű§Ù„", + "nl": "Ű§Ù„Ù‡ÙˆÙ„Ù†ŰŻÙŠŰ©", + "pa-IN": "Ű§Ù„ŰšÙ†ŰŹŰ§ŰšÙŠŰ©", + "pl": "Ű§Ù„ŰšÙˆÙ„Ù†ŰŻÙŠŰ©", + "pt-BR": "Ű§Ù„ŰšŰ±ŰȘŰșŰ§Ù„ÙŠŰ© Ű§Ù„ŰšŰ±Ű§ŰČÙŠÙ„ÙŠŰ© (Ű§Ù„ŰšŰ±Ű§ŰČيل)", + "pt-PT": "Ű§Ù„ŰšŰ±ŰȘŰșŰ§Ù„ÙŠŰ© Ű§Ù„ŰŁÙˆŰ±ÙˆŰšÙŠŰ© (Ű§Ù„ŰšŰ±ŰȘŰșŰ§Ù„)", + "ro-RO": "Ű§Ù„Ű±ÙˆÙ…Ű§Ù†ÙŠŰ©", + "ru": "Ű§Ù„Ű±ÙˆŰłÙŠŰ©", + "sk-SK": "Ű§Ù„ŰłÙ„ÙˆÙŰ§ÙƒÙŠŰ©", + "sl-SI": "Ű§Ù„ŰłÙ„ÙˆÙÙŠÙ†ÙŠŰ©", + "sq-AL": "Ű§Ù„ŰŁÙ„ŰšŰ§Ù†ÙŠŰ©", + "sr": "Ű§Ù„Ű”Ű±ŰšÙŠŰ©", + "sv": "Ű§Ù„ŰłÙˆÙŠŰŻÙŠŰ©", + "sw": "Ű§Ù„ŰłÙˆŰ§Ű­Ù„ÙŠŰ©", + "ta-IN": "Ű§Ù„ŰȘŰ§Ù…ÙŠÙ„ÙŠŰ©", + "te-IN": "Ű§Ù„ŰȘيلوŰșÙˆÙŠŰ©", + "th": "Ű§Ù„ŰȘŰ§ÙŠÙ„Ű§Ù†ŰŻÙŠŰ©", + "tl-PH": "Ű§Ù„ÙÙ„ŰšÙŠÙ†ÙŠŰ©", + "tr": "Ű§Ù„ŰȘŰ±ÙƒÙŠŰ©", + "ug": "Ű§Ù„ŰŁÙˆÙŠŰșÙˆŰ±ÙŠŰ©", + "uk-UA": "Ű§Ù„ŰŁÙˆÙƒŰ±Ű§Ù†ÙŠŰ©", + "ur": "Ű§Ù„ŰŁÙˆŰ±ŰŻÙŠŰ©", + "vi": "Ű§Ù„ÙÙŠŰȘÙ†Ű§Ù…ÙŠŰ©", + "yue": "Ű§Ù„ÙƒÙŽÙ†Ù’ŰȘÙÙˆÙ†ÙŠŰ©", + "zh-CN": "Ű§Ù„Ű”ÙŠÙ†ÙŠŰ© (Ű§Ù„Ű”ÙŠÙ†)", + "zh-HK": "Ű§Ù„Ű”ÙŠÙ†ÙŠŰ© (هونŰș كونŰș)", + "zh-Hant": "Ű§Ù„Ű”ÙŠÙ†ÙŠŰ© Ű§Ù„ŰȘÙ‚Ù„ÙŠŰŻÙŠŰ©" + }, + "az-AZ": { + "af-ZA": "Afrika dili", + "ar": "Ərəbcə", + "az-AZ": "Azərbaycan dili", + "bg-BG": "Bulqar dili", + "bn-BD": "Banqladeß dili", + "bs-BA": "Bosniya dili", + "ca": "Katalan dili", + "cs": "Çex dili", + "da": "Danimarka dili", + "de": "Alman dili", + "el": "Yunan dili", + "en": "İngilis dili", + "es": "İspan dili", + "et-EE": "Eston dili", + "eu": "Bask dili", + "fa-IR": "Farsca", + "fi": "Fin dili", + "fr": "Fransız dili", + "ga-IE": "İrland dili", + "gl-ES": "Qalisiya dili", + "gu-IN": "Qucarat dili", + "he": "İvrit dili", + "hi-IN": "Hind dili", + "hr-HR": "Xorvat dili", + "hu": "Macar dili", + "id": "İndoneziya dili", + "it": "İtalyan dili", + "ja": "Yapon dili", + "ka-GE": "GĂŒrcĂŒ dili", + "kk-KZ": "Kazak dili", + "km-KH": "Kxmer dili", + "kn-IN": "Kannada dili", + "ko": "Koreya dili", + "ky-KG": "Qırğız dili", + "lt-LT": "Litva dili", + "lv-LV": "Latıß dili", + "mk-MK": "Makedon dili", + "ml-IN": "Malayalam dili", + "mr-IN": "Marathi dili", + "ms": "Malay dili", + "my": "Birma dili", + "nb": "Norveç dili", + "nl": "Niderland dili", + "pa-IN": "Pəncabi dili", + "pl": "Polyak dili", + "pt-BR": "Portuqal dili (Braziliya)", + "pt-PT": "Portuqal dili (Portuqaliya)", + "ro-RO": "Rumın dili", + "ru": "Rus dili", + "sk-SK": "Slovak dili", + "sl-SI": "Sloven dili", + "sq-AL": "Alban dili", + "sr": "Serb dili", + "sv": "İsveç dili", + "sw": "Suahili dili", + "ta-IN": "Tamil dili", + "te-IN": "Teluqu dili", + "th": "Tay dili", + "tl-PH": "Filippin dili", + "tr": "TĂŒrk dili", + "ug": "Uyğur dili", + "uk-UA": "Ukrayna dili", + "ur": "Urdu dili", + "vi": "Vyetnam dili", + "yue": "Kanton dili", + "zh-CN": "Çin dili (Çin)", + "zh-HK": "Çin dili (Honkonq)", + "zh-Hant": "Çin dili (Klassik)" + }, + "bg-BG": { + "af-ZA": "АфроĐșĐ°ĐœŃ", + "ar": "АрабсĐșĐž", + "az-AZ": "АзДрбаĐčĐŽĐ¶Đ°ĐœŃĐșĐž", + "bg-BG": "БългарсĐșĐž", + "bn-BD": "Đ‘Đ”ĐœĐłĐ°Đ»ŃĐșĐž", + "bs-BA": "Đ‘ĐŸŃĐœĐ”ĐœŃĐșĐž", + "ca": "ĐšĐ°Ń‚Đ°Đ»ĐŸĐœŃĐșĐž", + "cs": "ЧДшĐșĐž", + "da": "ДатсĐșĐž", + "de": "ĐĐ”ĐŒŃĐșĐž", + "el": "ГръцĐșĐž", + "en": "ĐĐœĐłĐ»ĐžĐčсĐșĐž", + "es": "Đ˜ŃĐżĐ°ĐœŃĐșĐž", + "et-EE": "Đ•ŃŃ‚ĐŸĐœŃĐșĐž", + "eu": "БасĐșĐž", + "fa-IR": "ĐŸĐ”Ń€ŃĐžĐčсĐșĐž", + "fi": "Đ€ĐžĐœŃĐșĐž", + "fr": "Đ€Ń€Đ”ĐœŃĐșĐž", + "ga-IE": "Đ˜Ń€Đ»Đ°ĐœĐŽŃĐșĐž", + "gl-ES": "ГалОсОĐčсĐșĐž", + "gu-IN": "Đ“ŃƒĐŽĐ¶Đ°Ń€Đ°Ń‚Đž", + "he": "ИĐČрот", + "hi-IN": "Đ„ĐžĐœĐŽĐž", + "hr-HR": "ЄърĐČатсĐșĐž", + "hu": "ĐŁĐœĐłĐ°Ń€ŃĐșĐž", + "id": "Đ˜ĐœĐŽĐŸĐœĐ”Đ·ĐžĐčсĐșĐž", + "it": "Đ˜Ń‚Đ°Đ»ĐžĐ°ĐœŃĐșĐž", + "ja": "ĐŻĐżĐŸĐœŃĐșĐž", + "ka-GE": "Đ“Ń€ŃƒĐ·ĐžĐœŃĐșĐž", + "kk-KZ": "КазахсĐșĐž", + "km-KH": "ĐšŃ…ĐŒĐ”Ń€ŃĐșĐž", + "kn-IN": "ĐšĐ°ĐœĐœĐ°ĐŽĐ°", + "ko": "ĐšĐŸŃ€Đ”ĐčсĐșĐž", + "ky-KG": "КОргОзĐșĐž", + "lt-LT": "Đ›ĐžŃ‚ĐŸĐČсĐșĐž", + "lv-LV": "ЛатĐČĐžĐčсĐșĐž", + "mk-MK": "МаĐșĐ”ĐŽĐŸĐœŃĐșĐž", + "ml-IN": "ĐœĐ°Đ»Đ°ŃĐ»Đ°ĐŒ", + "mr-IN": "Марато", + "ms": "ĐœĐ°Đ»Đ°ĐčсĐșĐž", + "my": "Đ‘ĐžŃ€ĐŒĐ°ĐœŃĐșĐž", + "nb": "ĐĐŸŃ€ĐČДжĐșĐž", + "nl": "ĐĐžĐŽĐ”Ń€Đ»Đ°ĐœĐŽŃĐșĐž", + "pa-IN": "ĐŸĐ”ĐœĐŽĐ¶Đ°Đ±ŃĐșĐž", + "pl": "ĐŸĐŸĐ»ŃĐșĐž", + "pt-BR": "ĐŸĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃĐșĐž (Đ‘Ń€Đ°Đ·ĐžĐ»ĐžŃ)", + "pt-PT": "ĐŸĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃĐșĐž (ĐŸĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ĐžŃ)", + "ro-RO": "Đ ŃƒĐŒŃŠĐœŃĐșĐž", + "ru": "РусĐșĐž", + "sk-SK": "ĐĄĐ»ĐŸĐČашĐșĐž", + "sl-SI": "ĐĄĐ»ĐŸĐČĐ”ĐœŃĐșĐž", + "sq-AL": "ĐĐ»Đ±Đ°ĐœŃĐșĐž", + "sr": "ХръбсĐșĐž", + "sv": "ĐšĐČДЎсĐșĐž", + "sw": "ĐĄŃƒĐ°Ń…ĐžĐ»Đž", + "ta-IN": "ĐąĐ°ĐŒĐžĐ»ŃĐșĐž", + "te-IN": "йДлугу", + "th": "йаĐčсĐșĐž", + "tl-PH": "Đ€ĐžĐ»ĐžĐżĐžĐœŃĐșĐž", + "tr": "бурсĐșĐž", + "ug": "ĐŁĐčгурсĐșĐž", + "uk-UA": "ĐŁĐșŃ€Đ°ĐžĐœŃĐșĐž", + "ur": "УрЮу", + "vi": "Đ’ĐžĐ”Ń‚ĐœĐ°ĐŒŃĐșĐž", + "yue": "ĐšĐ°ĐœŃ‚ĐŸĐœŃĐșĐž", + "zh-CN": "КотаĐčсĐșĐž (КотаĐč)", + "zh-HK": "КотаĐčсĐșĐž (Đ„ĐŸĐœĐșĐŸĐœĐł)", + "zh-Hant": "КотаĐčсĐșĐž (Ń‚Ń€Đ°ĐŽĐžŃ†ĐžĐŸĐœĐ”Đœ)" + }, + "bn-BD": { + "af-ZA": "àŠ†àŠ«à§àŠ°àŠżàŠ•àŠŸàŠš", + "ar": "àŠ†àŠ°àŠŹà§€", + "az-AZ": "àŠ†àŠœàŠŸàŠ°àŠŹàŠŸàŠ‡àŠœàŠŸàŠšà§€", + "bg-BG": "àŠŹà§àŠČàŠ—à§‡àŠ°àŠżàŠŻàŠŒ", + "bn-BD": "àŠŹàŠŸàŠ‚àŠČàŠŸ", + "bs-BA": "àŠŹàŠžàŠšà§€àŠŻàŠŒ", + "ca": "àŠ•àŠŸàŠ€àŠŸàŠČàŠŸàŠš", + "cs": "àŠšà§‡àŠ•", + "da": "àŠĄà§‡àŠšàŠżàŠ¶", + "de": "àŠœàŠŸàŠ°à§àŠźàŠŸàŠš", + "el": "àŠ—à§àŠ°àŠżàŠ•", + "en": "àŠ‡àŠ‚àŠ°à§‡àŠœàŠż", + "es": "àŠžà§àŠȘà§àŠŻàŠŸàŠšàŠżàŠ¶", + "et-EE": "àŠàŠžà§àŠ€à§‹àŠšà§€àŠŻàŠŒ", + "eu": "àŠŹàŠŸàŠžà§àŠ•", + "fa-IR": "àŠ«àŠŸàŠ°à§àŠžàŠż", + "fi": "àŠ«àŠżàŠšàŠżàŠ¶", + "fr": "àŠ«àŠ°àŠŸàŠžàŠż", + "ga-IE": "àŠ†àŠ‡àŠ°àŠżàŠ¶", + "gl-ES": "àŠ—à§àŠŻàŠŸàŠČàŠżàŠ¶àŠżàŠŻàŠŒ", + "gu-IN": "àŠ—à§àŠœàŠ°àŠŸàŠŸàŠż", + "he": "àŠčàŠżàŠŹà§àŠ°à§", + "hi-IN": "àŠčàŠżàŠšà§àŠŠàŠż", + "hr-HR": "àŠ•à§àŠ°à§‹àŠŻàŠŒà§‡àŠ¶à§€àŠŻàŠŒ", + "hu": "àŠčàŠŸàŠ™à§àŠ—à§‡àŠ°à§€àŠŻàŠŒ", + "id": "àŠ‡àŠšà§àŠŠà§‹àŠšà§‡àŠ¶à§€àŠŻàŠŒ", + "it": "àŠ‡àŠ€àŠŸàŠČàŠżàŠŻàŠŒ", + "ja": "àŠœàŠŸàŠȘàŠŸàŠšàŠż", + "ka-GE": "àŠœàŠ°à§àŠœàŠżàŠŻàŠŒàŠŸàŠš", + "kk-KZ": "àŠ•àŠŸàŠœàŠŸàŠ–", + "km-KH": "àŠ–àŠźà§‡àŠ°", + "kn-IN": "àŠ•àŠšà§àŠšàŠĄàŠŒ", + "ko": "àŠ•à§‹àŠ°àŠżàŠŻàŠŒàŠŸàŠš", + "ky-KG": "àŠ•àŠżàŠ°à§àŠ—àŠżàŠœ", + "lt-LT": "àŠČàŠżàŠ„à§àŠŻàŠŒà§‡àŠšà§€àŠŻàŠŒ", + "lv-LV": "àŠČàŠŸàŠ€à§â€ŒàŠ­à§€àŠŻàŠŒ", + "mk-MK": "àŠźà§àŠŻàŠŸàŠžàŠżàŠĄà§‹àŠšà§€àŠŻàŠŒ", + "ml-IN": "àŠźàŠŸàŠČàŠŸàŠŻàŠŒàŠŸàŠČàŠŸàŠź", + "mr-IN": "àŠźàŠŸàŠ°àŠŸàŠ àŠż", + "ms": "àŠźàŠŸàŠČàŠŻàŠŒ", + "my": "àŠŹàŠ°à§àŠźàŠż", + "nb": "àŠšàŠ°àŠ“àŠŻàŠŒà§‡àŠœàŠżàŠŻàŠŒàŠŸàŠš àŠŹà§‹àŠ•àŠźàŠŸàŠČ", + "nl": "àŠ“àŠČàŠšà§àŠŠàŠŸàŠœ", + "pa-IN": "àŠȘàŠŸàŠžà§àŠœàŠŸàŠŹà§€", + "pl": "àŠȘোàŠČàŠżàŠ¶", + "pt-BR": "àŠȘàŠ°à§àŠ€à§àŠ—à§€àŠœ (àŠŹà§àŠ°àŠŸàŠœàŠżàŠČ)", + "pt-PT": "àŠȘàŠ°à§àŠ€à§àŠ—à§€àŠœ (àŠ‡àŠ‰àŠ°à§‹àŠȘ)", + "ro-RO": "àŠ°à§‹àŠźàŠŸàŠšà§€àŠŻàŠŒ", + "ru": "àŠ°à§àŠ¶", + "sk-SK": "àŠžà§àŠČà§‹àŠ­àŠŸàŠ•", + "sl-SI": "àŠžà§àŠČà§‹àŠ­à§‡àŠšà§€àŠŻàŠŒ", + "sq-AL": "àŠ†àŠČàŠŹà§‡àŠšà§€àŠŻàŠŒ", + "sr": "àŠžàŠŸàŠ°à§àŠŹà§€àŠŻàŠŒ", + "sv": "àŠžà§àŠ‡àŠĄàŠżàŠ¶", + "sw": "àŠžà§‹àŠŻàŠŒàŠŸàŠčàŠżàŠČàŠż", + "ta-IN": "àŠ€àŠŸàŠźàŠżàŠČ", + "te-IN": "àŠ€à§‡àŠČà§àŠ—à§", + "th": "àŠ„àŠŸàŠ‡", + "tl-PH": "àŠ«àŠżàŠČàŠżàŠȘàŠżàŠšà§‹", + "tr": "àŠ€à§àŠ°à§àŠ•à§€", + "ug": "àŠ‰àŠ‡àŠ˜à§àŠ°", + "uk-UA": "àŠ‡àŠ‰àŠ•à§àŠ°à§‡àŠšà§€àŠŻàŠŒ", + "ur": "àŠ‰àŠ°à§àŠŠà§", + "vi": "àŠ­àŠżàŠŻàŠŒà§‡àŠ€àŠšàŠŸàŠźà§€", + "yue": "àŠ•à§àŠŻàŠŸàŠšà§àŠŸà§‹àŠšàŠżàŠœ", + "zh-CN": "àŠšà§€àŠšàŠŸ (àŠšà§€àŠš)", + "zh-HK": "àŠšà§€àŠšàŠŸ (àŠčàŠ‚àŠ•àŠ‚)", + "zh-Hant": "àŠšà§€àŠšàŠŸ (àŠàŠ€àŠżàŠčà§àŠŻàŠŹàŠŸàŠčী)" + }, + "bs-BA": { + "af-ZA": "afrikaans", + "ar": "arapski", + "az-AZ": "azerbajdĆŸanski", + "bg-BG": "bugarski", + "bn-BD": "bengalski", + "bs-BA": "bosanski", + "ca": "katalonski", + "cs": "čeĆĄki", + "da": "danski", + "de": "njemački", + "el": "grčki", + "en": "engleski", + "es": "ĆĄpanski", + "et-EE": "estonski", + "eu": "baskijski", + "fa-IR": "perzijski", + "fi": "finski", + "fr": "francuski", + "ga-IE": "irski", + "gl-ES": "galicijski", + "gu-IN": "gudĆŸaratski", + "he": "hebrejski", + "hi-IN": "hindski", + "hr-HR": "hrvatski", + "hu": "mađarski", + "id": "indonezijski", + "it": "talijanski", + "ja": "japanski", + "ka-GE": "gruzijski", + "kk-KZ": "kazaĆĄki", + "km-KH": "kmerski", + "kn-IN": "karnatački", + "ko": "korejski", + "ky-KG": "kirgiski", + "lt-LT": "litavski", + "lv-LV": "latvijski", + "mk-MK": "makedonski", + "ml-IN": "malajalamski", + "mr-IN": "marathski", + "ms": "malajski", + "my": "burmanski", + "nb": "norveĆĄki bokmĂ„l", + "nl": "nizozemski", + "pa-IN": "pandĆŸapski", + "pl": "poljski", + "pt-BR": "brazilski portugalski", + "pt-PT": "europski portugalski", + "ro-RO": "rumunjski", + "ru": "ruski", + "sk-SK": "slovački", + "sl-SI": "slovenski", + "sq-AL": "albanski", + "sr": "srpski", + "sv": "ĆĄvedski", + "sw": "svahilski", + "ta-IN": "tamilski", + "te-IN": "teluĆĄki", + "th": "tajski", + "tl-PH": "filipinski", + "tr": "turski", + "ug": "ujgurski", + "uk-UA": "ukrajinski", + "ur": "urdski", + "vi": "vijetnamski", + "yue": "kantonski", + "zh-CN": "kineski (Kina)", + "zh-HK": "kineski (Hong Kong)", + "zh-Hant": "kineski (tradicionalni)" + }, + "ca": { + "af-ZA": "afrikaans", + "ar": "Ă rab", + "az-AZ": "azerbaidjanĂšs", + "bg-BG": "bĂșlgar", + "bn-BD": "bengalĂ­", + "bs-BA": "bosniĂ ", + "ca": "catalĂ ", + "cs": "txec", + "da": "danĂšs", + "de": "alemany", + "el": "grec", + "en": "anglĂšs", + "es": "espanyol", + "et-EE": "estoniĂ ", + "eu": "e", + "fa-IR": "persa", + "fi": "finĂšs", + "fr": "francĂšs", + "ga-IE": "irlandĂšs", + "gl-ES": "gallec", + "gu-IN": "gujarati", + "he": "hebreu", + "hi-IN": "hindi", + "hr-HR": "croat", + "hu": "hongarĂšs", + "id": "indonesi", + "it": "italiĂ ", + "ja": "japonĂšs", + "ka-GE": "georgiĂ ", + "kk-KZ": "kazakh", + "km-KH": "khmer", + "kn-IN": "kannada", + "ko": "coreĂ ", + "ky-KG": "kirguĂ­s", + "lt-LT": "lituĂ ", + "lv-LV": "letĂł", + "mk-MK": "macedoni", + "ml-IN": "malaiĂ lam", + "mr-IN": "marathi", + "ms": "malai", + "my": "birmĂ ", + "nb": "noruec bokmĂ„l", + "nl": "neerlandĂšs", + "pa-IN": "panjabi", + "pl": "polonĂšs", + "pt-BR": "portuguĂšs del Brasil", + "pt-PT": "portuguĂšs de Portugal", + "ro-RO": "romanĂšs", + "ru": "rus", + "sk-SK": "eslovac", + "sl-SI": "eslovĂš", + "sq-AL": "albanĂšs", + "sr": "serbi", + "sv": "suec", + "sw": "suahili", + "ta-IN": "tĂ mil", + "te-IN": "telugu", + "th": "tailandĂšs", + "tl-PH": "filipĂ­", + "tr": "turc", + "ug": "uigur", + "uk-UA": "ucraĂŻnĂšs", + "ur": "urdu", + "vi": "vietnamita", + "yue": "cantonĂšs", + "zh-CN": "xinĂšs", + "zh-HK": "xinĂšs de Hong Kong", + "zh-Hant": "xinĂšs tradicional" + }, + "cs": { + "af-ZA": "AfrikĂĄnĆĄtina", + "ar": "ArabĆĄtina", + "az-AZ": "ÁzerbĂĄjdĆŸĂĄnĆĄtina", + "bg-BG": "BulharĆĄtina", + "bn-BD": "BengĂĄlĆĄtina", + "bs-BA": "BosenĆĄtina", + "ca": "KatalĂĄnĆĄtina", + "cs": "ČeĆĄtina", + "da": "DĂĄnĆĄtina", + "de": "Němčina", + "el": "Ƙečtina", + "en": "Angličtina", + "es": "Ć panělĆĄtina", + "et-EE": "EstonĆĄtina", + "eu": "basc", + "fa-IR": "PerĆĄtina", + "fi": "FinĆĄtina", + "fr": "FrancouzĆĄtina", + "ga-IE": "IrĆĄtina", + "gl-ES": "GalicijĆĄtina", + "gu-IN": "GudĆŸarĂĄtĆĄtina", + "he": "HebrejĆĄtina", + "hi-IN": "HindĆĄtina", + "hr-HR": "ChorvatĆĄtina", + "hu": "MaďarĆĄtina", + "id": "Indonéƥtina", + "it": "ItalĆĄtina", + "ja": "JaponĆĄtina", + "ka-GE": "GruzĂ­nĆĄtina", + "kk-KZ": "KazaĆĄtina", + "km-KH": "KhmĂ©rĆĄtina", + "kn-IN": "KannadĆĄtina", + "ko": "KorejĆĄtina", + "ky-KG": "KyrgyzĆĄtina", + "lt-LT": "LitevĆĄtina", + "lv-LV": "LotyĆĄtina", + "mk-MK": "MakedonĆĄtina", + "ml-IN": "MalajĂĄlamĆĄtina", + "mr-IN": "MarĂĄthĆĄtina", + "ms": "MalajĆĄtina", + "my": "BarmĆĄtina", + "nb": "NorĆĄtina", + "nl": "NizozemĆĄtina", + "pa-IN": "PaƈdĆŸĂĄbĆĄtina", + "pl": "PolĆĄtina", + "pt-BR": "PortugalĆĄtina (brazilskĂĄ)", + "pt-PT": "PortugalĆĄtina (evropskĂĄ)", + "ro-RO": "RumunĆĄtina", + "ru": "RuĆĄtina", + "sk-SK": "SlovenĆĄtina", + "sl-SI": "SlovinĆĄtina", + "sq-AL": "AlbĂĄnĆĄtina", + "sr": "SrbĆĄtina", + "sv": "Ć vĂ©dĆĄtina", + "sw": "SvahilĆĄtina", + "ta-IN": "TamilĆĄtina", + "te-IN": "TelugĆĄtina", + "th": "ThajĆĄtina", + "tl-PH": "FilipĂ­nĆĄtina", + "tr": "Turečtina", + "ug": "UjgurĆĄtina", + "uk-UA": "UkrajinĆĄtina", + "ur": "UrdĆĄtina", + "vi": "VietnamĆĄtina", + "yue": "KantonĆĄtina", + "zh-CN": "ČínĆĄtina (Čína)", + "zh-HK": "ČínĆĄtina (Hongkong)", + "zh-Hant": "ČínĆĄtina (tradičnĂ­)" + }, + "da": { + "af-ZA": "Afrikaans", + "ar": "Arabisk", + "az-AZ": "Aserbajdsjansk", + "bg-BG": "Bulgarsk", + "bn-BD": "Bengali", + "bs-BA": "Bosnisk", + "ca": "Catalansk", + "cs": "Tjekkisk", + "da": "Dansk", + "de": "Tysk", + "el": "GrĂŠsk", + "en": "Engelsk", + "es": "Spansk", + "et-EE": "Estisk", + "eu": "Baskisk", + "fa-IR": "Persisk", + "fi": "Finsk", + "fr": "Fransk", + "ga-IE": "Irsk", + "gl-ES": "Galicisk", + "gu-IN": "Gujarati", + "he": "Hebraisk", + "hi-IN": "Hindi", + "hr-HR": "Kroatisk", + "hu": "Ungarsk", + "id": "Indonesisk", + "it": "Italiensk", + "ja": "Japansk", + "ka-GE": "Georgisk", + "kk-KZ": "Kasakhisk", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Koreansk", + "ky-KG": "Kirgisisk", + "lt-LT": "Litauisk", + "lv-LV": "Lettisk", + "mk-MK": "Makedonsk", + "ml-IN": "Malayalam", + "mr-IN": "Marathisk", + "ms": "Malajisk", + "my": "Burmesisk", + "nb": "BokmĂ„l", + "nl": "Nederlandsk", + "pa-IN": "Punjabisk", + "pl": "Polsk", + "pt-BR": "Brasiliansk portugisisk", + "pt-PT": "EuropĂŠisk portugisisk", + "ro-RO": "RumĂŠnsk", + "ru": "Russisk", + "sk-SK": "Slovakisk", + "sl-SI": "Slovensk", + "sq-AL": "Albansk", + "sr": "Serbisk", + "sv": "Svensk", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "Filippinsk", + "tr": "Tyrkisk", + "ug": "Uygurisk", + "uk-UA": "Ukrainsk", + "ur": "Urdu", + "vi": "Vietnamesisk", + "yue": "Kantonesisk", + "zh-CN": "Kinesisk (Kina)", + "zh-HK": "Kinesisk (Hongkong)", + "zh-Hant": "Traditionelt kinesisk" + }, + "de": { + "af-ZA": "Afrikaans", + "ar": "Arabisch", + "az-AZ": "Aserbaidschanisch", + "bg-BG": "Bulgarisch", + "bn-BD": "Bengalisch", + "bs-BA": "Bosnisch", + "ca": "Katalanisch", + "cs": "Tschechisch", + "da": "DĂ€nisch", + "de": "Deutsch", + "el": "Griechisch", + "en": "Englisch", + "es": "Spanisch", + "et-EE": "Estnisch", + "eu": "Baskisch", + "fa-IR": "Persisch", + "fi": "Finnisch", + "fr": "Französisch", + "ga-IE": "Irisch", + "gl-ES": "Galizisch", + "gu-IN": "Gujarati", + "he": "HebrĂ€isch", + "hi-IN": "Hindi", + "hr-HR": "Kroatisch", + "hu": "Ungarisch", + "id": "Indonesisch", + "it": "Italienisch", + "ja": "Japanisch", + "ka-GE": "Georgisch", + "kk-KZ": "Kasachisch", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Koreanisch", + "ky-KG": "Kirgisisch", + "lt-LT": "Litauisch", + "lv-LV": "Lettisch", + "mk-MK": "Mazedonisch", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Malaiisch", + "my": "Birmanisch", + "nb": "Norwegisch", + "nl": "NiederlĂ€ndisch", + "pa-IN": "Punjabi", + "pl": "Polnisch", + "pt-BR": "Portugiesisch (Brasilien)", + "pt-PT": "Portugiesisch (Portugal)", + "ro-RO": "RumĂ€nisch", + "ru": "Russisch", + "sk-SK": "Slowakisch", + "sl-SI": "Slowenisch", + "sq-AL": "Albanisch", + "sr": "Serbisch", + "sv": "Schwedisch", + "sw": "Suaheli", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "ThailĂ€ndisch", + "tl-PH": "Filipino", + "tr": "TĂŒrkisch", + "ug": "Uigurisch", + "uk-UA": "Ukrainisch", + "ur": "Urdu", + "vi": "Vietnamesisch", + "yue": "Kantonesisch", + "zh-CN": "Chinesisch", + "zh-HK": "Chinesisch (Hongkong)", + "zh-Hant": "Chinesisch (traditionell)" + }, + "el": { + "af-ZA": "ΑφρÎčÎșÎŹÎ±ÎœÏ‚", + "ar": "ΑραÎČÎčÎșÎŹ", + "az-AZ": "ΑζΔρΌπαϊτζαΜÎčÎșÎŹ", + "bg-BG": "Î’ÎżÏ…Î»ÎłÎ±ÏÎčÎșÎŹ", + "bn-BD": "ΒΔγγαλÎčÎșÎŹ", + "bs-BA": "Î’ÎżÏƒÎœÎčαÎșÎŹ", + "ca": "ΚαταλαΜÎčÎșÎŹ", + "cs": "΀σΔχÎčÎșÎŹ", + "da": "ΔαΜÎčÎșÎŹ", + "de": "ΓΔρΌαΜÎčÎșÎŹ", + "el": "ΕλληΜÎčÎșÎŹ", + "en": "ΑγγλÎčÎșÎŹ", + "es": "ΙσπαΜÎčÎșÎŹ", + "et-EE": "Î•ÏƒÎžÎżÎœÎčÎșÎŹ", + "eu": "ΒασÎșÎčÎșÎŹ", + "fa-IR": "ΠΔρσÎčÎșÎŹ", + "fi": "ΊÎčΜλαΜΎÎčÎșÎŹ", + "fr": "ΓαλλÎčÎșÎŹ", + "ga-IE": "ΙρλαΜΎÎčÎșÎŹ", + "gl-ES": "ΓαλÎčÎșÎčÎ±ÎœÎŹ", + "gu-IN": "ΓÎșÎżÏ…Ï„Î¶Î±ÏÎŹÏ„Îč", + "he": "ΕÎČραϊÎșÎŹ", + "hi-IN": "Î§ÎŻÎœÏ„Îč", + "hr-HR": "ÎšÏÎżÎ±Ï„ÎčÎșÎŹ", + "hu": "ÎŸÏ…ÎłÎłÏÎčÎșÎŹ", + "id": "Î™ÎœÎŽÎżÎœÎ·ÏƒÎčαÎșÎŹ", + "it": "ΙταλÎčÎșÎŹ", + "ja": "ΙαπωΜÎčÎșÎŹ", + "ka-GE": "Î“Î”Ï‰ÏÎłÎčÎ±ÎœÎŹ", + "kk-KZ": "ΚαζαÎșÎčÎșÎŹ", + "km-KH": "ΧΌΔρ", + "kn-IN": "ÎšÎŹÎœÎ±ÎœÏ„Î±", + "ko": "ÎšÎżÏÎ”Î±Ï„ÎčÎșÎŹ", + "ky-KG": "ΚÎčÏÎłÎčζÎčÎșÎŹ", + "lt-LT": "ΛÎčÎžÎżÏ…Î±ÎœÎčÎșÎŹ", + "lv-LV": "Î›Î”Ï„ÎżÎœÎčÎșÎŹ", + "mk-MK": "ΣλαÎČÎżÎŒÎ±ÎșÎ”ÎŽÎżÎœÎčÎșÎŹ", + "ml-IN": "ÎœÎ±Î»Î±ÎłÎčÎ±Î»ÎŹÎŒ", + "mr-IN": "ΜαραΞÎčÎșÎŹ", + "ms": "ΜαλαÎčσÎčÎ±ÎœÎŹ", + "my": "ΒÎčρΌαΜÎčÎșÎŹ", + "nb": "ÎÎżÏÎČηγÎčÎșÎŹ ÎœÏ€ÎżÎșÎŒÎŹÎ»", + "nl": "ΟλλαΜΎÎčÎșÎŹ", + "pa-IN": "Î Î±ÎœÏ„Î¶ÎŹÎŒÏ€Îč", + "pl": "Î ÎżÎ»Ï‰ÎœÎčÎșÎŹ", + "pt-BR": "Î ÎżÏÏ„ÎżÎłÎ±Î»ÎčÎșÎŹ ΒραζÎčÎ»ÎŻÎ±Ï‚", + "pt-PT": "Î ÎżÏÏ„ÎżÎłÎ±Î»ÎčÎșÎŹ Ευρώπης", + "ro-RO": "ÎĄÎżÏ…ÎŒÎ±ÎœÎčÎșÎŹ", + "ru": "ÎĄÏ‰ÏƒÎčÎșÎŹ", + "sk-SK": "ΣλοÎČαÎșÎčÎșÎŹ", + "sl-SI": "ΣλοÎČΔΜÎčÎșÎŹ", + "sq-AL": "ΑλÎČαΜÎčÎșÎŹ", + "sr": "ÎŁÎ”ÏÎČÎčÎșÎŹ", + "sv": "ÎŁÎżÏ…Î·ÎŽÎčÎșÎŹ", + "sw": "ÎŁÎżÏ…Î±Ï‡ÎŻÎ»Îč", + "ta-IN": "Î€Î±ÎŒÎŻÎ»", + "te-IN": "Î€Î”Î»ÎżÏÎłÎșÎżÏ…", + "th": "΀αϊλαΜΎÎčÎșÎŹ", + "tl-PH": "ΊÎčλÎčππÎčΜέζÎčÎșα", + "tr": "Î€ÎżÏ…ÏÎșÎčÎșÎŹ", + "ug": "ΟυÎčÎłÎżÏ…ÏÎčÎșÎŹ", + "uk-UA": "ΟυÎșραΜÎčÎșÎŹ", + "ur": "ÎŸÏÏÎœÏ„ÎżÏ…", + "vi": "ΒÎčΔτΜαΌÎčÎșÎŹ", + "yue": "ÎšÎ±ÎœÏ„ÎżÎœÎ­Î¶ÎčÎșα", + "zh-CN": "ΚÎčΜΔζÎčÎșÎŹ (ÎšÎŻÎœÎ±)", + "zh-HK": "ΚÎčΜΔζÎčÎșÎŹ (Î§ÎżÎœÎłÎș ÎšÎżÎœÎłÎș)", + "zh-Hant": "Î Î±ÏÎ±ÎŽÎżÏƒÎčαÎșÎŹ ΚÎčΜΔζÎčÎșÎŹ" + }, + "es": { + "af-ZA": "afrikĂĄans", + "ar": "ĂĄrabe", + "az-AZ": "azerbaiyano", + "bg-BG": "bĂșlgaro", + "bn-BD": "bengalĂ­", + "bs-BA": "bosnio", + "ca": "catalĂĄn", + "cs": "checo", + "da": "danĂ©s", + "de": "alemĂĄn", + "el": "griego", + "en": "inglĂ©s", + "es": "español", + "et-EE": "estonio", + "eu": "euskera", + "fa-IR": "persa", + "fi": "finĂ©s", + "fr": "francĂ©s", + "ga-IE": "irlandĂ©s", + "gl-ES": "gallego", + "gu-IN": "guyaratĂ­", + "he": "hebreo", + "hi-IN": "hindi", + "hr-HR": "croata", + "hu": "hĂșngaro", + "id": "indonesio", + "it": "italiano", + "ja": "japonĂ©s", + "ka-GE": "georgiano", + "kk-KZ": "kazajo", + "km-KH": "jemer", + "kn-IN": "canarĂ©s", + "ko": "coreano", + "ky-KG": "kirguĂ­s", + "lt-LT": "lituano", + "lv-LV": "letĂłn", + "mk-MK": "macedonio", + "ml-IN": "malayĂĄlam", + "mr-IN": "maratĂ­", + "ms": "malayo", + "my": "birmano", + "nb": "noruego bokmal", + "nl": "neerlandĂ©s", + "pa-IN": "punyabĂ­", + "pl": "polaco", + "pt-BR": "portuguĂ©s de Brasil", + "pt-PT": "portuguĂ©s de Portugal", + "ro-RO": "rumano", + "ru": "ruso", + "sk-SK": "eslovaco", + "sl-SI": "esloveno", + "sq-AL": "albanĂ©s", + "sr": "serbio", + "sv": "sueco", + "sw": "suajili", + "ta-IN": "tamil", + "te-IN": "telugu", + "th": "tailandĂ©s", + "tl-PH": "filipino", + "tr": "turco", + "ug": "uigur", + "uk-UA": "ucraniano", + "ur": "urdu", + "vi": "vietnamita", + "yue": "cantonĂ©s", + "zh-CN": "chino", + "zh-HK": "chino de Hong Kong", + "zh-Hant": "chino tradicional" + }, + "et-EE": { + "af-ZA": "afrikaani", + "ar": "araabia", + "az-AZ": "aserbaidĆŸaani", + "bg-BG": "bulgaaria", + "bn-BD": "bengali", + "bs-BA": "bosnia", + "ca": "katalaani", + "cs": "tĆĄehhi", + "da": "taani", + "de": "saksa", + "el": "kreeka", + "en": "inglise", + "es": "hispaania", + "et-EE": "eesti", + "eu": "baski", + "fa-IR": "pĂ€rsia", + "fi": "soome", + "fr": "prantsuse", + "ga-IE": "iiri", + "gl-ES": "galeegi", + "gu-IN": "gudĆŸarati", + "he": "heebrea", + "hi-IN": "hindi", + "hr-HR": "horvaadi", + "hu": "ungari", + "id": "indoneesia", + "it": "itaalia", + "ja": "jaapani", + "ka-GE": "gruusia", + "kk-KZ": "kasahhi", + "km-KH": "khmeeri", + "kn-IN": "kannada", + "ko": "korea", + "ky-KG": "kirgiisi", + "lt-LT": "leedu", + "lv-LV": "lĂ€ti", + "mk-MK": "makedoonia", + "ml-IN": "malajalami", + "mr-IN": "marathi", + "ms": "malai", + "my": "birma", + "nb": "norra bokmĂ„li", + "nl": "hollandi", + "pa-IN": "pandĆŸabi", + "pl": "poola", + "pt-BR": "portugali (Brasiilia)", + "pt-PT": "portugali (Euroopa)", + "ro-RO": "rumeenia", + "ru": "vene", + "sk-SK": "slovaki", + "sl-SI": "sloveeni", + "sq-AL": "albaania", + "sr": "serbia", + "sv": "rootsi", + "sw": "suahiili", + "ta-IN": "tamili", + "te-IN": "telugu", + "th": "tai", + "tl-PH": "filipiini", + "tr": "tĂŒrgi", + "ug": "uiguuri", + "uk-UA": "ukraina", + "ur": "urdu", + "vi": "vietnami", + "yue": "kantoni", + "zh-CN": "hiina (Hiina)", + "zh-HK": "hiina (Hongkong)", + "zh-Hant": "traditsiooniline hiina" + }, + "eu": { + "af-ZA": "Afrikaansa", + "ar": "Arabiera", + "az-AZ": "Azerbaijanera", + "bg-BG": "Bulgariera", + "bn-BD": "Bengalera", + "bs-BA": "Bosniera", + "ca": "Katalana", + "cs": "Txekiera", + "da": "Daniera", + "de": "Alemana", + "el": "Greziera", + "en": "Ingelesa", + "es": "Gaztelania", + "et-EE": "Estoniera", + "eu": "Euskara", + "fa-IR": "Persiera", + "fi": "Finlandiera", + "fr": "Frantsesa", + "ga-IE": "Irlandera", + "gl-ES": "Galiziera", + "gu-IN": "Gujaratera", + "he": "Hebreera", + "hi-IN": "Hindia", + "hr-HR": "Kroaziera", + "hu": "Hungariera", + "id": "Indonesiera", + "it": "Italiera", + "ja": "Japoniera", + "ka-GE": "Georgiera", + "kk-KZ": "Kazakhera", + "km-KH": "Khmerera", + "kn-IN": "Kannada", + "ko": "Koreera", + "ky-KG": "Kirgizera", + "lt-LT": "Lituaniera", + "lv-LV": "Letoniera", + "mk-MK": "Mazedoniera", + "ml-IN": "Malabarera", + "mr-IN": "Marathera", + "ms": "Malaysiera", + "my": "Birmaniera", + "nb": "Norvegiera", + "nl": "Nederlandera", + "pa-IN": "Punjabera", + "pl": "Poloniera", + "pt-BR": "Portugesa (Brasil)", + "pt-PT": "Portugesa (Portugal)", + "ro-RO": "Errumaniera", + "ru": "Errusiera", + "sk-SK": "Eslovakiera", + "sl-SI": "Esloveniera", + "sq-AL": "Albaniera", + "sr": "Serbiera", + "sv": "Suediera", + "sw": "Swahilia", + "ta-IN": "Tamilera", + "te-IN": "Telugua", + "th": "Thailandiera", + "tl-PH": "Filipinera", + "tr": "Turkiera", + "ug": "Uigurrera", + "uk-UA": "Ukrainera", + "ur": "Urdua", + "vi": "Vietnamera", + "yue": "Kantonera", + "zh-CN": "Txinera (Txina)", + "zh-HK": "Txinera (Hong Kong)", + "zh-Hant": "Txinera tradizionala" + }, + "fa-IR": { + "af-ZA": "ŰąÙŰ±ÛŒÙ‚Ű§ÛŒÛŒ", + "ar": "ŰčŰ±ŰšÛŒ", + "az-AZ": "ŰąŰ°Ű±ŰšŰ§ÛŒŰŹŰ§Ù†ÛŒ", + "bg-BG": "ŰšÙ„ŰșŰ§Ű±ÛŒ", + "bn-BD": "ŰšÙ†ÚŻŰ§Ù„ÛŒ", + "bs-BA": "ŰšÙˆŰłÙ†ÛŒŰ§ÛŒÛŒ", + "ca": "کۧŰȘŰ§Ù„Ű§Ù†", + "cs": "چکی", + "da": "ŰŻŰ§Ù†Ù…Ű§Ű±Ú©ÛŒ", + "de": "ŰąÙ„Ù…Ű§Ù†ÛŒ", + "el": "ÛŒÙˆÙ†Ű§Ù†ÛŒ", + "en": "Ű§Ù†ÚŻÙ„ÛŒŰłÛŒ", + "es": "Ű§ŰłÙŸŰ§Ù†ÛŒŰ§ÛŒÛŒ", + "et-EE": "ۧ۳ŰȘÙˆÙ†ÛŒŰ§ÛŒÛŒ", + "eu": "ŰšŰ§ŰłÚ©ÛŒ", + "fa-IR": "ÙŰ§Ű±ŰłÛŒ", + "fi": "ÙÙ†Ù„Ű§Ù†ŰŻÛŒ", + "fr": "ÙŰ±Ű§Ù†ŰłÙˆÛŒ", + "ga-IE": "Ű§ÛŒŰ±Ù„Ù†ŰŻÛŒ", + "gl-ES": "ÚŻŰ§Ù„ÛŒŰłÛŒŰ§ÛŒÛŒ", + "gu-IN": "گۏ۱ۧŰȘی", + "he": "ŰčŰšŰ±ÛŒ", + "hi-IN": "Ù‡Ù†ŰŻÛŒ", + "hr-HR": "Ú©Ű±ÙˆŰ§ŰȘ", + "hu": "Ù…ŰŹŰ§Ű±ÛŒ", + "id": "Ű§Ù†ŰŻÙˆÙ†ŰČÛŒŰ§ÛŒÛŒ", + "it": "Ű§ÛŒŰȘŰ§Ù„ÛŒŰ§ÛŒÛŒ", + "ja": "Ú˜Ű§ÙŸÙ†ÛŒ", + "ka-GE": "ÚŻŰ±ŰŹÛŒ", + "kk-KZ": "قŰČŰ§Ù‚", + "km-KH": "ŰźÙ…Ű±", + "kn-IN": "Ú©Ù†Ű§ŰŻŰ§", + "ko": "Ú©Ű±Ù‡â€ŒŰ§ÛŒ", + "ky-KG": "Ù‚Ű±Ù‚ÛŒŰČی", + "lt-LT": "لیŰȘÙˆŰ§Ù†ÛŒŰ§ÛŒÛŒ", + "lv-LV": "لŰȘÙˆÙ†ÛŒŰ§ÛŒÛŒ", + "mk-MK": "Ù…Ù‚ŰŻÙˆÙ†ÛŒ", + "ml-IN": "Ù…Ű§Ù„Ű§ÛŒŰ§Ù„Ű§Ù…ÛŒ", + "mr-IN": "Ù…Ű±Ű§ŰȘی", + "ms": "Ù…Ű§Ù„Ű§ÛŒÛŒ", + "my": "ŰšŰ±Ù…Ù‡â€ŒŰ§ÛŒ", + "nb": "Ù†Ű±ÙˆÚ˜ÛŒ ŰšÙˆÚ©â€ŒÙ…ÙÙ„", + "nl": "Ù‡Ù„Ù†ŰŻÛŒ", + "pa-IN": "ÙŸÙ†ŰŹŰ§ŰšÛŒ", + "pl": "Ù„Ù‡ŰłŰȘŰ§Ù†ÛŒ", + "pt-BR": "ÙŸŰ±ŰȘŰșŰ§Ù„ÛŒ ۚ۱ŰČیل", + "pt-PT": "ÙŸŰ±ŰȘŰșŰ§Ù„ÛŒ Ű§Ű±ÙˆÙŸŰ§", + "ro-RO": "Ű±ÙˆÙ…Ű§Ù†ÛŒŰ§ÛŒÛŒ", + "ru": "Ű±ÙˆŰłÛŒ", + "sk-SK": "Ű§ŰłÙ„ÙˆŰ§Ú©ÛŒ", + "sl-SI": "Ű§ŰłÙ„ÙˆÙˆÙ†ÛŒŰ§ÛŒÛŒ", + "sq-AL": "ŰąÙ„ŰšŰ§Ù†ÛŒŰ§ÛŒÛŒ", + "sr": "Ű”Ű±ŰšÛŒ", + "sv": "ŰłÙˆŰŠŰŻÛŒ", + "sw": "ŰłÙˆŰ§Ű­ÛŒÙ„ÛŒ", + "ta-IN": "ŰȘŰ§Ù…ÛŒÙ„ÛŒ", + "te-IN": "ŰȘÙ„ÙˆÚŻÙˆ", + "th": "ŰȘŰ§ÛŒÙ„Ù†ŰŻÛŒ", + "tl-PH": "فیلیٟینی", + "tr": "ŰȘŰ±Ú©ÛŒ ۧ۳ŰȘŰ§Ù†ŰšÙˆÙ„ÛŒ", + "ug": "Ű§ÙˆÛŒŰșÙˆŰ±", + "uk-UA": "Ű§ÙˆÚ©Ű±Ű§ÛŒÙ†ÛŒ", + "ur": "Ű§Ű±ŰŻÙˆ", + "vi": "ویŰȘÙ†Ű§Ù…ÛŒ", + "yue": "Ú©Ű§Ù†ŰȘونی", + "zh-CN": "چینی (چین)", + "zh-HK": "چینی (Ù‡Ù†ÚŻâ€ŒÚ©Ù†ÚŻ)", + "zh-Hant": "چینی ŰłÙ†ŰȘی" + }, + "fi": { + "af-ZA": "afrikaans", + "ar": "arabia", + "az-AZ": "azeri", + "bg-BG": "bulgaria", + "bn-BD": "bengali", + "bs-BA": "bosnia", + "ca": "katalaani", + "cs": "tĆĄekki", + "da": "tanska", + "de": "saksa", + "el": "kreikka", + "en": "englanti", + "es": "espanja", + "et-EE": "viro", + "eu": "baski", + "fa-IR": "persia", + "fi": "suomi", + "fr": "ranska", + "ga-IE": "iiri", + "gl-ES": "galicia", + "gu-IN": "gudĆŸarati", + "he": "heprea", + "hi-IN": "hindi", + "hr-HR": "kroatia", + "hu": "unkari", + "id": "indonesia", + "it": "italia", + "ja": "japani", + "ka-GE": "georgia", + "kk-KZ": "kazakki", + "km-KH": "khmer", + "kn-IN": "kannada", + "ko": "korea", + "ky-KG": "kirgiisi", + "lt-LT": "liettua", + "lv-LV": "latvia", + "mk-MK": "makedonia", + "ml-IN": "malajalam", + "mr-IN": "marathi", + "ms": "malaiji", + "my": "burma", + "nb": "norjan bokmĂ„l", + "nl": "hollanti", + "pa-IN": "pandĆŸabi", + "pl": "puola", + "pt-BR": "brasilianportugali", + "pt-PT": "euroopanportugali", + "ro-RO": "romania", + "ru": "venĂ€jĂ€", + "sk-SK": "slovakki", + "sl-SI": "sloveeni", + "sq-AL": "albania", + "sr": "serbia", + "sv": "ruotsi", + "sw": "swahili", + "ta-IN": "tamili", + "te-IN": "telugu", + "th": "thai", + "tl-PH": "filipino", + "tr": "turkki", + "ug": "uiguuri", + "uk-UA": "ukraina", + "ur": "urdu", + "vi": "vietnam", + "yue": "kantoninkiina", + "zh-CN": "kiina (Kiina)", + "zh-HK": "kiina (Hongkong)", + "zh-Hant": "kiina (perinteinen)" + }, + "fr": { + "af-ZA": "afrikaans", + "ar": "arabe", + "az-AZ": "azerbaĂŻdjanais", + "bg-BG": "bulgare", + "bn-BD": "bengali", + "bs-BA": "bosniaque", + "ca": "catalan", + "cs": "tchĂšque", + "da": "danois", + "de": "allemand", + "el": "grec", + "en": "anglais", + "es": "espagnol", + "et-EE": "estonien", + "eu": "basque", + "fa-IR": "persan", + "fi": "finnois", + "fr": "français", + "ga-IE": "irlandais", + "gl-ES": "galicien", + "gu-IN": "goudjarati", + "he": "hĂ©breu", + "hi-IN": "hindi", + "hr-HR": "croate", + "hu": "hongrois", + "id": "indonĂ©sien", + "it": "italien", + "ja": "japonais", + "ka-GE": "gĂ©orgien", + "kk-KZ": "kazakh", + "km-KH": "khmer", + "kn-IN": "kannada", + "ko": "corĂ©en", + "ky-KG": "kirghize", + "lt-LT": "lituanien", + "lv-LV": "letton", + "mk-MK": "macĂ©donien", + "ml-IN": "malayalam", + "mr-IN": "marathi", + "ms": "malais", + "my": "birman", + "nb": "norvĂ©gien bokmĂ„l", + "nl": "nĂ©erlandais", + "pa-IN": "pendjabi", + "pl": "polonais", + "pt-BR": "portugais brĂ©silien", + "pt-PT": "portugais europĂ©en", + "ro-RO": "roumain", + "ru": "russe", + "sk-SK": "slovaque", + "sl-SI": "slovĂšne", + "sq-AL": "albanais", + "sr": "serbe", + "sv": "suĂ©dois", + "sw": "swahili", + "ta-IN": "tamoul", + "te-IN": "tĂ©lougou", + "th": "thaĂŻ", + "tl-PH": "filipino", + "tr": "turc", + "ug": "ouĂŻghour", + "uk-UA": "ukrainien", + "ur": "ourdou", + "vi": "vietnamien", + "yue": "cantonais", + "zh-CN": "chinois", + "zh-HK": "chinois", + "zh-Hant": "chinois traditionnel" + }, + "ga-IE": { + "af-ZA": "AfracĂĄinis", + "ar": "Araibis", + "az-AZ": "AsarbaiseĂĄinis", + "bg-BG": "BulgĂĄiris", + "bn-BD": "BeangĂĄilis", + "bs-BA": "Boisnis", + "ca": "CatalĂłinis", + "cs": "Seicis", + "da": "Danmhairgis", + "de": "GearmĂĄinis", + "el": "GrĂ©igis", + "en": "BĂ©arla", + "es": "SpĂĄinnis", + "et-EE": "EastĂłinis", + "eu": "Bascais", + "fa-IR": "Dairis", + "fi": "Fionlainnis", + "fr": "Fraincis", + "ga-IE": "Gaeilge", + "gl-ES": "GailĂ­sis", + "gu-IN": "GĂșisearĂĄitis", + "he": "Eabhrais", + "hi-IN": "HiondĂșis", + "hr-HR": "CrĂłitis", + "hu": "UngĂĄiris", + "id": "IndinĂ©isis", + "it": "IodĂĄilis", + "ja": "SeapĂĄinis", + "ka-GE": "Seoirsis", + "kk-KZ": "Casaicis", + "km-KH": "CimĂ©iris", + "kn-IN": "Cannadais", + "ko": "CĂłirĂ©is", + "ky-KG": "Cirgisis", + "lt-LT": "LiotuĂĄinis", + "lv-LV": "Laitvis", + "mk-MK": "MacadĂłinis", + "ml-IN": "MailĂ©alaimis", + "mr-IN": "Maraitis", + "ms": "Malaeis", + "my": "Burmais", + "nb": "Ioruais", + "nl": "ÍsiltĂ­ris", + "pa-IN": "PuinseĂĄibis", + "pl": "Polainnis", + "pt-BR": "PortaingĂ©ilis na BrasaĂ­le", + "pt-PT": "PortaingĂ©ilis na hEorpa", + "ro-RO": "RĂłmĂĄinis", + "ru": "RĂșisis", + "sk-SK": "SlĂłvaicis", + "sl-SI": "SlĂłivĂ©inis", + "sq-AL": "AlbĂĄinis", + "sr": "Seirbis", + "sv": "Sualainnis", + "sw": "SvahaĂ­lis", + "ta-IN": "Tamailis", + "te-IN": "TeileagĂșis", + "th": "TĂ©alainnis", + "tl-PH": "FilipĂ­nis", + "tr": "Tuircis", + "ug": "UigiĂșiris", + "uk-UA": "ÚcrĂĄinis", + "ur": "UrdĂșis", + "vi": "VĂ­tneaimis", + "yue": "Cantainis", + "zh-CN": "SĂ­nis (an tSĂ­n)", + "zh-HK": "SĂ­nis (Hong Cong)", + "zh-Hant": "SĂ­nis thraidisiĂșnta" + }, + "gl-ES": { + "af-ZA": "afrikaans", + "ar": "ĂĄrabe", + "az-AZ": "acerbaixano", + "bg-BG": "bĂșlgaro", + "bn-BD": "bengalĂ­", + "bs-BA": "bosnĂ­aco", + "ca": "catalĂĄn", + "cs": "checo", + "da": "danĂ©s", + "de": "alemĂĄn", + "el": "grego", + "en": "inglĂ©s", + "es": "español", + "et-EE": "estoniano", + "eu": "vasco", + "fa-IR": "persa", + "fi": "finĂ©s", + "fr": "francĂ©s", + "ga-IE": "irlandĂ©s", + "gl-ES": "galego", + "gu-IN": "guxarati", + "he": "hebreo", + "hi-IN": "hindi", + "hr-HR": "croata", + "hu": "hĂșngaro", + "id": "lingua indonesia", + "it": "italiano", + "ja": "xaponĂ©s", + "ka-GE": "xeorxiano", + "kk-KZ": "casaco", + "km-KH": "camboxano", + "kn-IN": "kanarĂ©s", + "ko": "coreano", + "ky-KG": "quirguiz", + "lt-LT": "lituano", + "lv-LV": "letĂłn", + "mk-MK": "macedonio", + "ml-IN": "malayalam", + "mr-IN": "marathi", + "ms": "malaio", + "my": "birmano", + "nb": "norueguĂ©s bokmĂ„l", + "nl": "neerlandĂ©s", + "pa-IN": "punjabi", + "pl": "polaco", + "pt-BR": "portuguĂ©s (Brasil)", + "pt-PT": "portuguĂ©s (Portugal)", + "ro-RO": "romanĂ©s", + "ru": "ruso", + "sk-SK": "eslovaco", + "sl-SI": "esloveno", + "sq-AL": "albanĂ©s", + "sr": "serbio", + "sv": "sueco", + "sw": "suahili", + "ta-IN": "tĂĄmil", + "te-IN": "telugu", + "th": "tailandĂ©s", + "tl-PH": "filipino", + "tr": "turco", + "ug": "uigur", + "uk-UA": "ucraĂ­no", + "ur": "urdĂș", + "vi": "vietnamita", + "yue": "cantonĂ©s", + "zh-CN": "chinĂ©s (China)", + "zh-HK": "chinĂ©s (Hong Kong)", + "zh-Hant": "chinĂ©s tradicional" + }, + "gu-IN": { + "af-ZA": "àȘ†àȘ«à«àȘ°àȘżàȘ•àȘšà«àȘž", + "ar": "àȘ…àȘ°àȘŹà«€", + "az-AZ": "àȘ…àȘàȘ°àȘŹà«ˆàȘœàȘŸàȘšà«€", + "bg-BG": "àȘŹàȘČ્àȘ—ેàȘ°àȘżàȘŻàȘš", + "bn-BD": "àȘŹàȘ‚àȘ—àȘŸàȘłà«€", + "bs-BA": "àȘŹà«‹àȘžà«àȘšàȘżàȘŻàȘš", + "ca": "àȘ•àȘ€àȘČàȘŸàȘš", + "cs": "àȘšà«‡àȘ•", + "da": "àȘĄà«‡àȘšàȘżàȘ¶", + "de": "àȘœàȘ°à«àȘźàȘš", + "el": "àȘ—્àȘ°à«€àȘ•", + "en": "àȘ…àȘ‚àȘ—્àȘ°à«‡àȘœà«€", + "es": "àȘžà«àȘȘેàȘšàȘżàȘ¶", + "et-EE": "àȘàȘžà«àȘŸà«‹àȘšàȘżàȘŻàȘš", + "eu": "àȘŹàȘŸàȘžà«àȘ•", + "fa-IR": "àȘ«àȘŸàȘ°àȘžà«€", + "fi": "àȘ«àȘżàȘšàȘżàȘ¶", + "fr": "àȘ«à«àȘ°à«‡àȘšà«àȘš", + "ga-IE": "àȘ†àȘ‡àȘ°àȘżàȘ¶", + "gl-ES": "àȘ—ેàȘČàȘżàȘ¶àȘżàȘŻàȘš", + "gu-IN": "àȘ—ુàȘœàȘ°àȘŸàȘ€à«€", + "he": "àȘčીàȘŹà«àȘ°à«", + "hi-IN": "àȘčàȘżàȘšà«àȘŠà«€", + "hr-HR": "àȘ•્àȘ°à«‹àȘàȘ¶àȘżàȘŻàȘš", + "hu": "àȘčàȘ‚àȘ—ેàȘ°àȘżàȘŻàȘš", + "id": "àȘ‡àȘšà«àȘĄà«‹àȘšà«‡àȘ¶àȘżàȘŻàȘš", + "it": "àȘ‡àȘŸàȘŸàȘČàȘżàȘŻàȘš", + "ja": "àȘœàȘŸàȘȘàȘŸàȘšà«€àȘ", + "ka-GE": "àȘœà«àȘŻà«‹àȘ°à«àȘœàȘżàȘŻàȘš", + "kk-KZ": "àȘ•àȘàȘŸàȘ–", + "km-KH": "àȘ–્àȘźà«‡àȘ°", + "kn-IN": "àȘ•àȘšà«àȘšàȘĄ", + "ko": "àȘ•à«‹àȘ°àȘżàȘŻàȘš", + "ky-KG": "àȘ•àȘżàȘ°à«àȘ—à«€àȘ", + "lt-LT": "àȘČàȘżàȘ„ુàȘ†àȘšàȘżàȘŻàȘš", + "lv-LV": "àȘČàȘŸàȘ€àȘ”àȘżàȘŻàȘš", + "mk-MK": "àȘźà«‡àȘžà«‡àȘĄà«‹àȘšàȘżàȘŻàȘš", + "ml-IN": "àȘźàȘČàȘŻàȘŸàȘČàȘź", + "mr-IN": "àȘźàȘ°àȘŸàȘ à«€", + "ms": "àȘźàȘČàȘŻ", + "my": "àȘŹàȘ°à«àȘźà«€àȘ", + "nb": "àȘšà«‹àȘ°à«àȘ”ેàȘœàȘżàȘŻàȘš àȘŹà«‹àȘ•àȘźàȘŸàȘČ", + "nl": "àȘĄàȘš", + "pa-IN": "àȘȘàȘ‚àȘœàȘŸàȘŹà«€", + "pl": "àȘȘોàȘČીàȘ¶", + "pt-BR": "àȘŹà«àȘ°àȘŸàȘàȘżàȘČીàȘŻàȘš àȘȘોàȘ°à«àȘŸà«àȘ—à«€àȘ", + "pt-PT": "àȘŻà«àȘ°à«‹àȘȘàȘżàȘŻàȘš àȘȘોàȘ°à«àȘŸà«àȘ—à«€àȘ", + "ro-RO": "àȘ°à«‹àȘźàȘŸàȘšàȘżàȘŻàȘš", + "ru": "àȘ°àȘ¶àȘżàȘŻàȘš", + "sk-SK": "àȘžà«àȘČોàȘ”ૅàȘ•", + "sl-SI": "àȘžà«àȘČોàȘ”ેàȘšàȘżàȘŻàȘš", + "sq-AL": "àȘ…àȘČ્àȘŹà«‡àȘšàȘżàȘŻàȘš", + "sr": "àȘžàȘ°à«àȘŹàȘżàȘŻàȘš", + "sv": "àȘžà«àȘ”ીàȘĄàȘżàȘ¶", + "sw": "àȘžà«àȘ”àȘŸàȘčàȘżàȘČી", + "ta-IN": "àȘ€àȘźàȘżàȘČ", + "te-IN": "àȘ€à«‡àȘČુàȘ—ુ", + "th": "àȘ„àȘŸàȘˆ", + "tl-PH": "àȘ«àȘżàȘČàȘżàȘȘàȘżàȘšà«‹", + "tr": "àȘ€à«àȘ°à«àȘ•à«€", + "ug": "àȘ‰àȘ‡àȘ—ુàȘ°", + "uk-UA": "àȘŻà«àȘ•્àȘ°à«‡àȘšàȘżàȘŻàȘš", + "ur": "àȘ‰àȘ°à«àȘŠà«‚", + "vi": "àȘ”àȘżàȘŻà«‡àȘ€àȘšàȘŸàȘźà«€àȘž", + "yue": "àȘ•ેàȘ‚àȘŸà«‹àȘšà«€àȘ", + "zh-CN": "àȘšàȘŸàȘ‡àȘšà«€àȘ (àȘšà«€àȘš)", + "zh-HK": "àȘšàȘŸàȘ‡àȘšà«€àȘ (àȘčોàȘ‚àȘ—àȘ•à«‹àȘ‚àȘ—)", + "zh-Hant": "àȘȘàȘŸàȘ°àȘ‚àȘȘàȘ°àȘżàȘ• àȘšàȘŸàȘ‡àȘšà«€àȘ" + }, + "he": { + "af-ZA": "ŚŚ€ŚšŚ™Ś§ŚŚ ŚĄ", + "ar": "ŚąŚšŚ‘Ś™ŚȘ", + "az-AZ": "ŚŚ–ŚšŚ™ŚȘ", + "bg-BG": "Ś‘Ś•ŚœŚ’ŚšŚ™ŚȘ", + "bn-BD": "Ś‘Ś Ś’ŚœŚ™ŚȘ", + "bs-BA": "Ś‘Ś•ŚĄŚ Ś™ŚȘ", + "ca": "Ś§Ś˜ŚœŚŚ Ś™ŚȘ", + "cs": "ŚŠŚłŚ›Ś™ŚȘ", + "da": "ړڠڙŚȘ", + "de": "Ś’ŚšŚžŚ Ś™ŚȘ", + "el": "ڙڕڕڠڙŚȘ", + "en": "ŚŚ Ś’ŚœŚ™ŚȘ", + "es": "ŚĄŚ€ŚšŚ“Ś™ŚȘ", + "et-EE": "ŚŚĄŚ˜Ś•Ś Ś™ŚȘ", + "eu": "Ś‘ŚĄŚ§Ś™ŚȘ", + "fa-IR": "Ś€ŚšŚĄŚ™ŚȘ", + "fi": "ڀڙڠڙŚȘ", + "fr": "ŚŠŚšŚ€ŚȘŚ™ŚȘ", + "ga-IE": "ŚŚ™ŚšŚ™ŚȘ", + "gl-ES": "Ś’ŚœŚ™ŚĄŚ™ŚȘ", + "gu-IN": "ڒڕڒ'ŚšŚŚ˜Ś™ŚȘ", + "he": "ŚąŚ‘ŚšŚ™ŚȘ", + "hi-IN": "ڔڙڠړڙ", + "hr-HR": "Ś§ŚšŚ•ŚŚ˜Ś™ŚȘ", + "hu": "Ś”Ś•Ś Ś’ŚšŚ™ŚȘ", + "id": "ڐڙڠړڕڠږڙŚȘ", + "it": "ŚŚ™Ś˜ŚœŚ§Ś™ŚȘ", + "ja": "ڙڀڠڙŚȘ", + "ka-GE": "Ś’ŚŚ•ŚšŚ’Ś™ŚȘ", + "kk-KZ": "ڧږڗڙŚȘ", + "km-KH": "Ś—ŚžŚšŚ™ŚȘ", + "kn-IN": "ڧڐڠړڔ", + "ko": "Ś§Ś•ŚšŚ™ŚŚ Ś™ŚȘ", + "ky-KG": "Ś§Ś™ŚšŚ’Ś™Ś–Ś™ŚȘ", + "lt-LT": "ŚœŚ™Ś˜ŚŚ™ŚȘ", + "lv-LV": "ŚœŚ˜Ś‘Ś™ŚȘ", + "mk-MK": "ŚžŚ§Ś“Ś•Ś Ś™ŚȘ", + "ml-IN": "ŚžŚœŚŚ™ŚŚœŚŚ", + "mr-IN": "ŚžŚšŚŚ˜Ś”Ś™ŚȘ", + "ms": "ŚžŚœŚŚ™ŚȘ", + "my": "Ś‘Ś•ŚšŚžŚ–Ś™ŚȘ", + "nb": "Ś Ś•ŚšŚ•Ś•Ś’Ś™ŚȘ ŚĄŚ€ŚšŚ•ŚȘŚ™ŚȘ", + "nl": "Ś”Ś•ŚœŚ Ś“Ś™ŚȘ", + "pa-IN": "ڀڠڒ'ڐڑڙ", + "pl": "Ś€Ś•ŚœŚ Ś™ŚȘ", + "pt-BR": "Ś€Ś•ŚšŚ˜Ś•Ś’Ś–Ś™ŚȘ (Ś‘ŚšŚ–Ś™Śœ)", + "pt-PT": "Ś€Ś•ŚšŚ˜Ś•Ś’Ś–Ś™ŚȘ (Ś€Ś•ŚšŚ˜Ś•Ś’Śœ)", + "ro-RO": "ŚšŚ•ŚžŚ Ś™ŚȘ", + "ru": "ŚšŚ•ŚĄŚ™ŚȘ", + "sk-SK": "ŚĄŚœŚ•Ś‘Ś§Ś™ŚȘ", + "sl-SI": "ŚĄŚœŚ•Ś‘Ś Ś™ŚȘ", + "sq-AL": "ŚŚœŚ‘Ś Ś™ŚȘ", + "sr": "ŚĄŚšŚ‘Ś™ŚȘ", + "sv": "کڕڕړڙŚȘ", + "sw": "ŚĄŚ•Ś•ŚŚ”Ś™ŚœŚ™", + "ta-IN": "Ś˜ŚžŚ™ŚœŚ™ŚȘ", + "te-IN": "Ś˜ŚœŚ•Ś’Ś•", + "th": "ŚȘڐڙŚȘ", + "tl-PH": "Ś€Ś™ŚœŚ™Ś€Ś™Ś Ś™ŚȘ", + "tr": "Ś˜Ś•ŚšŚ§Ś™ŚȘ", + "ug": "ŚŚ•Ś™Ś’Ś•ŚšŚ™ŚȘ", + "uk-UA": "ŚŚ•Ś§ŚšŚŚ™Ś Ś™ŚȘ", + "ur": "ŚŚ•ŚšŚ“Ś•", + "vi": "Ś•Ś™Ś™Ś˜Ś ŚŚžŚ™ŚȘ", + "yue": "Ś§Ś Ś˜Ś•Ś Ś–Ś™ŚȘ", + "zh-CN": "ŚĄŚ™Ś Ś™ŚȘ (ŚĄŚ™ŚŸ)", + "zh-HK": "ŚĄŚ™Ś Ś™ŚȘ (ڔڕڠڒ ڧڕڠڒ)", + "zh-Hant": "ŚĄŚ™Ś Ś™ŚȘ ŚžŚĄŚ•ŚšŚȘŚ™ŚȘ" + }, + "hi-IN": { + "af-ZA": "à€…à€«à€Œà„à€°à„€à€•à„€", + "ar": "à€…à€°à€Źà„€", + "az-AZ": "à€…à€œà€Œà€°à€Źà„ˆà€œà€Ÿà€šà„€", + "bg-BG": "à€Źà„à€Čà„à€—à€Ÿà€°à€żà€Żà€Ÿà€ˆ", + "bn-BD": "à€Źà€‚à€—à€Ÿà€Čà„€", + "bs-BA": "à€Źà„‹à€žà„à€šà€żà€Żà€Ÿà€ˆ", + "ca": "à€•à€Ÿà€€à€Ÿà€Čà€Ÿà€š", + "cs": "à€šà„‡à€•", + "da": "à€Ąà„‡à€šà€żà€¶", + "de": "à€œà€°à„à€źà€š", + "el": "à€Żà„‚à€šà€Ÿà€šà„€", + "en": "à€…à€‚à€—à„à€°à„‡à€œà€Œà„€", + "es": "à€žà„à€Șà„‡à€šà€żà€¶", + "et-EE": "à€à€žà„à€Ÿà„‹à€šà€żà€Żà€Ÿà€ˆ", + "eu": "à€Źà€Ÿà€žà„à€•", + "fa-IR": "à€«à€Œà€Ÿà€°à€žà„€", + "fi": "à€«à€Œà€żà€šà€żà€¶", + "fr": "à€«à€Œà„à€°à„‡à€‚à€š", + "ga-IE": "à€†à€Żà€°à€żà€¶", + "gl-ES": "à€—à„ˆà€Čà€żà€¶à€żà€Żà€š", + "gu-IN": "à€—à„à€œà€°à€Ÿà€€à„€", + "he": "à€čà€żà€Źà„à€°à„‚", + "hi-IN": "à€čà€żà€šà„à€Šà„€", + "hr-HR": "à€•à„à€°à„‹à€à€¶à€żà€Żà€Ÿà€ˆ", + "hu": "à€čà€‚à€—à„‡à€°à€żà€Żà€Ÿà€ˆ", + "id": "à€‡à€‚à€Ąà„‹à€šà„‡à€¶à€żà€Żà€Ÿà€ˆ", + "it": "à€‡à€€à€Ÿà€Čà€”à„€", + "ja": "à€œà€Ÿà€Șà€Ÿà€šà„€", + "ka-GE": "à€œà„‰à€°à„à€œà€żà€Żà€Ÿà€ˆ", + "kk-KZ": "à€•à€œà€Œà€Ÿà€–à€Œ", + "km-KH": "à€–à€źà„‡à€°", + "kn-IN": "à€•à€šà„à€šà€Ąà€Œ", + "ko": "à€•à„‹à€°à€żà€Żà€Ÿà€ˆ", + "ky-KG": "à€•à€żà€°à„à€—à„€à€œà€Œ", + "lt-LT": "à€Čà€żà€„à„à€†à€šà€żà€Żà€Ÿà€ˆ", + "lv-LV": "à€Čà€Ÿà€€à€”à€żà€Żà€Ÿà€ˆ", + "mk-MK": "à€źà€•à€Šà„‚à€šà€żà€Żà€Ÿà€ˆ", + "ml-IN": "à€źà€Čà€Żà€Ÿà€Čà€ź", + "mr-IN": "à€źà€°à€Ÿà€ à„€", + "ms": "à€źà€Čà€Ż", + "my": "à€Źà€°à„à€źà„€à€œà€Œ", + "nb": "à€šà„‰à€°à„à€”à„‡à€œà€żà€Żà€Ÿà€ˆ à€Źà„‹à€•à€źà€Ÿà€Č", + "nl": "à€Ąà€š", + "pa-IN": "à€Șà€‚à€œà€Ÿà€Źà„€", + "pl": "à€Șà„‹à€Čà€żà€¶", + "pt-BR": "à€Źà„à€°à€Ÿà€œà€Œà„€à€Čà„€ à€Șà„à€°à„à€€à€—à€Ÿà€Čà„€", + "pt-PT": "à€Żà„‚à€°à„‹à€Șà„€à€Ż à€Șà„à€°à„à€€à€—à€Ÿà€Čà„€", + "ro-RO": "à€°à„‹à€źà€Ÿà€šà€żà€Żà€Ÿà€ˆ", + "ru": "à€°à„‚à€žà„€", + "sk-SK": "à€žà„à€Čà„‹à€”à€Ÿà€•", + "sl-SI": "à€žà„à€Čà„‹à€”à„‡à€šà€żà€Żà€Ÿà€ˆ", + "sq-AL": "à€…à€Čà„à€Źà€Ÿà€šà€żà€Żà€Ÿà€ˆ", + "sr": "à€žà€°à„à€Źà€żà€Żà€Ÿà€ˆ", + "sv": "à€žà„à€”à„€à€Ąà€żà€¶", + "sw": "à€žà„à€”à€Ÿà€čà€żà€Čà„€", + "ta-IN": "à€€à€źà€żà€Č", + "te-IN": "à€€à„‡à€Čà„à€—à„‚", + "th": "à€„à€Ÿà€ˆ", + "tl-PH": "à€«à€Œà€żà€Čà€żà€Șà„€à€šà„‹", + "tr": "à€€à„à€°à„à€•à„€", + "ug": "à€‰à€‡à€—à€°", + "uk-UA": "à€Żà„‚à€•à„à€°à„‡à€šà€żà€Żà€Ÿà€ˆ", + "ur": "à€‰à€°à„à€Šà„‚", + "vi": "à€”à€żà€Żà€€à€šà€Ÿà€źà„€", + "yue": "à€•à„ˆà€‚à€Ÿà„‹à€šà„€à€œà€Œ", + "zh-CN": "à€šà„€à€šà„€ (à€šà„€à€š)", + "zh-HK": "à€šà„€à€šà„€ (à€čà€Ÿà€à€— à€•à€Ÿà€à€—)", + "zh-Hant": "à€Șà€Ÿà€°à€‚à€Șà€°à€żà€• à€šà„€à€šà„€" + }, + "hr-HR": { + "af-ZA": "afrikaans", + "ar": "arapski", + "az-AZ": "azerbajdĆŸanski", + "bg-BG": "bugarski", + "bn-BD": "bengalski", + "bs-BA": "bosanski", + "ca": "katalonski", + "cs": "čeĆĄki", + "da": "danski", + "de": "njemački", + "el": "grčki", + "en": "engleski", + "es": "ĆĄpanjolski", + "et-EE": "estonski", + "eu": "baskijski", + "fa-IR": "perzijski", + "fi": "finski", + "fr": "francuski", + "ga-IE": "irski", + "gl-ES": "galicijski", + "gu-IN": "gudĆŸaratski", + "he": "hebrejski", + "hi-IN": "hindski", + "hr-HR": "hrvatski", + "hu": "mađarski", + "id": "indonezijski", + "it": "talijanski", + "ja": "japanski", + "ka-GE": "gruzijski", + "kk-KZ": "kazaĆĄki", + "km-KH": "kmerski", + "kn-IN": "karnatački", + "ko": "korejski", + "ky-KG": "kirgiski", + "lt-LT": "litavski", + "lv-LV": "latvijski", + "mk-MK": "makedonski", + "ml-IN": "malajalamski", + "mr-IN": "marathski", + "ms": "malajski", + "my": "burmanski", + "nb": "norveĆĄki bokmĂ„l", + "nl": "nizozemski", + "pa-IN": "pandĆŸapski", + "pl": "poljski", + "pt-BR": "brazilski portugalski", + "pt-PT": "europski portugalski", + "ro-RO": "rumunjski", + "ru": "ruski", + "sk-SK": "slovački", + "sl-SI": "slovenski", + "sq-AL": "albanski", + "sr": "srpski", + "sv": "ĆĄvedski", + "sw": "svahilski", + "ta-IN": "tamilski", + "te-IN": "teluĆĄki", + "th": "tajski", + "tl-PH": "filipinski", + "tr": "turski", + "ug": "ujgurski", + "uk-UA": "ukrajinski", + "ur": "urdski", + "vi": "vijetnamski", + "yue": "kantonski", + "zh-CN": "kineski (Kina)", + "zh-HK": "kineski (Hong Kong)", + "zh-Hant": "kineski (tradicionalni)" + }, + "hu": { + "af-ZA": "Afrikaans", + "ar": "Arab", + "az-AZ": "AzerbajdzsĂĄni", + "bg-BG": "BolgĂĄr", + "bn-BD": "Bangla", + "bs-BA": "BosnyĂĄk", + "ca": "KatalĂĄn", + "cs": "Cseh", + "da": "DĂĄn", + "de": "NĂ©met", + "el": "Görög", + "en": "Angol", + "es": "Spanyol", + "et-EE": "Észt", + "eu": "Baszk", + "fa-IR": "Perzsa", + "fi": "Finn", + "fr": "Francia", + "ga-IE": "Ír", + "gl-ES": "Gallego", + "gu-IN": "GudzsarĂĄti", + "he": "HĂ©ber", + "hi-IN": "Hindi", + "hr-HR": "HorvĂĄt", + "hu": "Magyar", + "id": "IndonĂ©z", + "it": "Olasz", + "ja": "JapĂĄn", + "ka-GE": "GrĂșz", + "kk-KZ": "Kazah", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Koreai", + "ky-KG": "Kirgiz", + "lt-LT": "LitvĂĄn", + "lv-LV": "Lett", + "mk-MK": "MacedĂłn", + "ml-IN": "MalajĂĄlam", + "mr-IN": "MarĂĄthi", + "ms": "MalĂĄj", + "my": "Burmai", + "nb": "NorvĂ©g", + "nl": "Holland", + "pa-IN": "PandzsĂĄbi", + "pl": "Lengyel", + "pt-BR": "BrazĂ­liai portugĂĄl", + "pt-PT": "EurĂłpai portugĂĄl", + "ro-RO": "RomĂĄn", + "ru": "Orosz", + "sk-SK": "SzlovĂĄk", + "sl-SI": "SzlovĂ©n", + "sq-AL": "AlbĂĄn", + "sr": "Szerb", + "sv": "SvĂ©d", + "sw": "SzuahĂ©li", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "FilippĂ­nĂł", + "tr": "Török", + "ug": "Ujgur", + "uk-UA": "UkrĂĄn", + "ur": "Urdu", + "vi": "VietnĂĄmi", + "yue": "Kantoni", + "zh-CN": "KĂ­nai (KĂ­na)", + "zh-HK": "KĂ­nai (Hongkong)", + "zh-Hant": "HagyomĂĄnyos kĂ­nai" + }, + "id": { + "af-ZA": "Afrikaans", + "ar": "Arab", + "az-AZ": "Azerbaijan", + "bg-BG": "Bulgaria", + "bn-BD": "Bengali", + "bs-BA": "Bosnia", + "ca": "Katalan", + "cs": "Ceko", + "da": "Denmark", + "de": "Jerman", + "el": "Yunani", + "en": "Inggris", + "es": "Spanyol", + "et-EE": "Estonia", + "eu": "Basque", + "fa-IR": "Persia", + "fi": "Finlandia", + "fr": "Prancis", + "ga-IE": "Irlandia", + "gl-ES": "Galisia", + "gu-IN": "Gujarat", + "he": "Ibrani", + "hi-IN": "Hindi", + "hr-HR": "Kroasia", + "hu": "Hungaria", + "id": "Indonesia", + "it": "Italia", + "ja": "Jepang", + "ka-GE": "Georgia", + "kk-KZ": "Kazakh", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Korea", + "ky-KG": "Kirgiz", + "lt-LT": "Lituania", + "lv-LV": "Latvia", + "mk-MK": "Makedonia", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Melayu", + "my": "Burma", + "nb": "BokmĂ„l Norwegia", + "nl": "Belanda", + "pa-IN": "Punjabi", + "pl": "Polandia", + "pt-BR": "Portugis (Brasil)", + "pt-PT": "Portugis (Eropa)", + "ro-RO": "Rumania", + "ru": "Rusia", + "sk-SK": "Slowakia", + "sl-SI": "Slovenia", + "sq-AL": "Albania", + "sr": "Serbia", + "sv": "Swedia", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "Filipino", + "tr": "Turki", + "ug": "Uyghur", + "uk-UA": "Ukraina", + "ur": "Urdu", + "vi": "Vietnam", + "yue": "Kanton", + "zh-CN": "Mandarin (Tiongkok)", + "zh-HK": "Mandarin (Hong Kong)", + "zh-Hant": "Mandarin Tradisional" + }, + "it": { + "af-ZA": "Afrikaans", + "ar": "Arabo", + "az-AZ": "Azero", + "bg-BG": "Bulgaro", + "bn-BD": "Bengalese", + "bs-BA": "Bosniaco", + "ca": "Catalano", + "cs": "Ceco", + "da": "Danese", + "de": "Tedesco", + "el": "Greco", + "en": "Inglese", + "es": "Spagnolo", + "et-EE": "Estone", + "eu": "Basco", + "fa-IR": "Persiano", + "fi": "Finlandese", + "fr": "Francese", + "ga-IE": "Irlandese", + "gl-ES": "Galiziano", + "gu-IN": "Gujarati", + "he": "Ebraico", + "hi-IN": "Hindi", + "hr-HR": "Croato", + "hu": "Ungherese", + "id": "Indonesiano", + "it": "Italiano", + "ja": "Giapponese", + "ka-GE": "Georgiano", + "kk-KZ": "Kazako", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Coreano", + "ky-KG": "Kirghiso", + "lt-LT": "Lituano", + "lv-LV": "Lettone", + "mk-MK": "Macedone", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Malese", + "my": "Birmano", + "nb": "Norvegese bokmĂ„l", + "nl": "Olandese", + "pa-IN": "Punjabi", + "pl": "Polacco", + "pt-BR": "Portoghese (brasiliano)", + "pt-PT": "Portoghese (europeo)", + "ro-RO": "Rumeno", + "ru": "Russo", + "sk-SK": "Slovacco", + "sl-SI": "Sloveno", + "sq-AL": "Albanese", + "sr": "Serbo", + "sv": "Svedese", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thailandese", + "tl-PH": "Filippino", + "tr": "Turco", + "ug": "Uiguro", + "uk-UA": "Ucraino", + "ur": "Urdu", + "vi": "Vietnamita", + "yue": "Cantonese", + "zh-CN": "Cinese (Cina)", + "zh-HK": "Cinese (Hong Kong)", + "zh-Hant": "Cinese tradizionale" + }, + "ja": { + "af-ZA": "ケフăƒȘă‚«ăƒŒăƒłă‚čèȘž", + "ar": "ă‚ąăƒ©ăƒ“ă‚ąèȘž", + "az-AZ": "ă‚ąă‚Œăƒ«ăƒă‚€ă‚žăƒŁăƒłèȘž", + "bg-BG": "ăƒ–ăƒ«ă‚ŹăƒȘケèȘž", + "bn-BD": "ăƒ™ăƒłă‚Źăƒ«èȘž", + "bs-BA": "ボă‚čニケèȘž", + "ca": "ă‚«ă‚żăƒ­ăƒ‹ă‚ąèȘž", + "cs": "チェコèȘž", + "da": "ăƒ‡ăƒłăƒžăƒŒă‚ŻèȘž", + "de": "ăƒ‰ă‚€ăƒ„èȘž", + "el": "ゼăƒȘă‚·ăƒŁèȘž", + "en": "英èȘž", + "es": "ă‚čăƒšă‚€ăƒłèȘž", + "et-EE": "スă‚čトニケèȘž", + "eu": "バă‚čクèȘž", + "fa-IR": "ăƒšăƒ«ă‚·ă‚ąèȘž", + "fi": "ăƒ•ă‚Łăƒłăƒ©ăƒłăƒ‰èȘž", + "fr": "ăƒ•ăƒ©ăƒłă‚čèȘž", + "ga-IE": "ă‚ąă‚€ăƒ«ăƒ©ăƒłăƒ‰èȘž", + "gl-ES": "ガăƒȘシスèȘž", + "gu-IN": "ă‚°ă‚žăƒŁăƒ©ăƒŒăƒˆèȘž", + "he": "ăƒ˜ăƒ–ăƒ©ă‚€èȘž", + "hi-IN": "ăƒ’ăƒłăƒ‡ă‚ŁăƒŒèȘž", + "hr-HR": "クロケチケèȘž", + "hu": "ハンガăƒȘăƒŒèȘž", + "id": "ă‚€ăƒłăƒ‰ăƒă‚·ă‚ąèȘž", + "it": "むタăƒȘケèȘž", + "ja": "æ—„æœŹèȘž", + "ka-GE": "ă‚žăƒ§ăƒŒă‚žă‚ąèȘž", + "kk-KZ": "ă‚«ă‚¶ăƒ•èȘž", + "km-KH": "ă‚ŻăƒĄăƒŒăƒ«èȘž", + "kn-IN": "ă‚«ăƒłăƒŠăƒ€èȘž", + "ko": "éŸ“ć›œèȘž", + "ky-KG": "ă‚­ăƒ«ă‚źă‚čèȘž", + "lt-LT": "ăƒȘトケニケèȘž", + "lv-LV": "ăƒ©ăƒˆăƒ“ă‚ąèȘž", + "mk-MK": "ăƒžă‚±ăƒ‰ăƒ‹ă‚ąèȘž", + "ml-IN": "ăƒžăƒ©ăƒ€ăƒŒăƒ©ăƒ èȘž", + "mr-IN": "ăƒžăƒ©ăƒŒăƒ†ă‚ŁăƒŒèȘž", + "ms": "ăƒžăƒŹăƒŒèȘž", + "my": "ăƒŸăƒŁăƒłăƒžăƒŒèȘž", + "nb": "ăƒŽăƒ«ă‚Šă‚§ăƒŒèȘž", + "nl": "ă‚Șăƒ©ăƒłăƒ€èȘž", + "pa-IN": "パンゾャブèȘž", + "pl": "ăƒăƒŒăƒ©ăƒłăƒ‰èȘž", + "pt-BR": "ăƒăƒ«ăƒˆă‚Źăƒ«èȘž (ăƒ–ăƒ©ă‚žăƒ«)", + "pt-PT": "ăƒăƒ«ăƒˆă‚Źăƒ«èȘž (ăƒšăƒŒăƒ­ăƒƒăƒ‘)", + "ro-RO": "ăƒ«ăƒŒăƒžăƒ‹ă‚ąèȘž", + "ru": "ăƒ­ă‚·ă‚ąèȘž", + "sk-SK": "ă‚čロバキケèȘž", + "sl-SI": "ă‚čロベニケèȘž", + "sq-AL": "ă‚ąăƒ«ăƒăƒ‹ă‚ąèȘž", + "sr": "ă‚»ăƒ«ăƒ“ă‚ąèȘž", + "sv": "ă‚čă‚Šă‚§ăƒŒăƒ‡ăƒłèȘž", + "sw": "ă‚čワヒăƒȘèȘž", + "ta-IN": "ă‚żăƒŸăƒ«èȘž", + "te-IN": "ăƒ†ăƒ«ă‚°èȘž", + "th": "タむèȘž", + "tl-PH": "フィăƒȘピノèȘž", + "tr": "ăƒˆăƒ«ă‚łèȘž", + "ug": "ă‚Šă‚€ă‚°ăƒ«èȘž", + "uk-UA": "ă‚Šă‚Żăƒ©ă‚€ăƒŠèȘž", + "ur": "ă‚Šăƒ«ăƒ‰ă‚„ăƒŒèȘž", + "vi": "ベトナムèȘž", + "yue": "ćșƒæ±èȘž", + "zh-CN": "äž­ć›œèȘž (äž­ć›œ)", + "zh-HK": "äž­ć›œèȘž (éŠ™æžŻ)", + "zh-Hant": "çčäœ“ć­—äž­ć›œèȘž" + }, + "ka-GE": { + "af-ZA": "áƒáƒ€áƒ áƒ˜áƒ™áƒŁáƒšáƒ˜", + "ar": "არაბული", + "az-AZ": "აზერბაიჯანული", + "bg-BG": "ბულგარული", + "bn-BD": "ბენგალური", + "bs-BA": "ბოსნიური", + "ca": "კაჱალონიური", + "cs": "áƒ©áƒ”áƒźáƒŁáƒ áƒ˜", + "da": "დანიური", + "de": "გერმანული", + "el": "áƒ‘áƒ”áƒ áƒ«áƒœáƒŁáƒšáƒ˜", + "en": "ინგლისური", + "es": "ესპანური", + "et-EE": "ესჱონური", + "eu": "ბასკური", + "fa-IR": "სპარსული", + "fi": "áƒ€áƒ˜áƒœáƒŁáƒ áƒ˜", + "fr": "áƒ€áƒ áƒáƒœáƒ’áƒŁáƒšáƒ˜", + "ga-IE": "ირლანდიური", + "gl-ES": "გალისიური", + "gu-IN": "გუჯარათი", + "he": "ებრაული", + "hi-IN": "ჰინდი", + "hr-HR": "ჼორვაჱიული", + "hu": "უნგრული", + "id": "ინდონეზიური", + "it": "იჱალიური", + "ja": "იაპონური", + "ka-GE": "áƒ„áƒáƒ áƒ—áƒŁáƒšáƒ˜", + "kk-KZ": "ყაზაჼური", + "km-KH": "áƒ„áƒ›áƒ”áƒ áƒŁáƒšáƒ˜", + "kn-IN": "კანადა", + "ko": "კორეული", + "ky-KG": "ყირგიზული", + "lt-LT": "ლიჱვური", + "lv-LV": "ლაჱვიური", + "mk-MK": "მაკედონიური", + "ml-IN": "მალაიალამური", + "mr-IN": "მარათული", + "ms": "მალაური", + "my": "ბირმული", + "nb": "ნორვეგიული ბოკმალი", + "nl": "ჰოლანდიური", + "pa-IN": "პენჯაბური", + "pl": "პოლონური", + "pt-BR": "Portuguese (Brazil)", + "pt-PT": "Portuguese (Portugal)", + "ro-RO": "რუმინული", + "ru": "რუსული", + "sk-SK": "სლოვაკური", + "sl-SI": "სლოვენური", + "sq-AL": "ალბანური", + "sr": "სერბული", + "sv": "ჹვედური", + "sw": "სუაჰილი", + "ta-IN": "ჱამილური", + "te-IN": "ჱელუგუ", + "th": "ჱაილანდური", + "tl-PH": "áƒ€áƒ˜áƒšáƒ˜áƒžáƒ˜áƒœáƒŁáƒ áƒ˜", + "tr": "áƒ—áƒŁáƒ áƒ„áƒŁáƒšáƒ˜", + "ug": "უი჊ური", + "uk-UA": "უკრაინული", + "ur": "ურდუ", + "vi": "ვიეჱნამური", + "yue": "კანჱონური", + "zh-CN": "áƒ©áƒ˜áƒœáƒŁáƒ áƒ˜ (ჩინეთი)", + "zh-HK": "áƒ©áƒ˜áƒœáƒŁáƒ áƒ˜ (ჰონკონგი)", + "zh-Hant": "ჱრადიáƒȘიული áƒ©áƒ˜áƒœáƒŁáƒ áƒ˜" + }, + "kk-KZ": { + "af-ZA": "афроĐșĐ°Đ°ĐœŃ тілі", + "ar": "араб тілі", + "az-AZ": "әзДрбаĐčĐ¶Đ°Đœ тілі", + "bg-BG": "Đ±ĐŸĐ»ĐłĐ°Ń€ тілі", + "bn-BD": "Đ±Đ°ĐœĐłĐ»Đ° тілі", + "bs-BA": "Đ±ĐŸŃĐœĐžŃ тілі", + "ca": "ĐșĐ°Ń‚Đ°Đ»ĐŸĐœĐŽŃ‹Ò› тіл", + "cs": "чДх тілі", + "da": "Юат тілі", + "de": "ĐœĐ”ĐŒŃ–Ń тілі", + "el": "грДĐș тілі", + "en": "Đ°Ò“Ń‹Đ»ŃˆŃ‹Đœ тілі", + "es": "ĐžŃĐżĐ°Đœ тілі", + "et-EE": "ŃŃŃ‚ĐŸĐœ тілі", + "eu": "басĐș тілі", + "fa-IR": "парсы тілі", + "fi": "Ń„ĐžĐœ тілі", + "fr": "Ń„Ń€Đ°ĐœŃ†ŃƒĐ· тілі", + "ga-IE": "ĐžŃ€Đ»Đ°ĐœĐŽŃ‹Ò› тіл", + "gl-ES": "галОсОĐč тілі", + "gu-IN": "ĐłŃƒĐŽĐ¶Đ°Ń€Đ°Ń‚Đž тілі", + "he": "ĐžĐČрот", + "hi-IN": "Ń…ĐžĐœĐŽĐž", + "hr-HR": "Ń…ĐŸŃ€ĐČат тілі", + "hu": "ĐČĐ”ĐœĐłŃ€ тілі", + "id": "ĐžĐœĐŽĐŸĐœĐ”Đ·ĐžŃ тілі", + "it": "ĐžŃ‚Đ°Đ»ŃŒŃĐœ тілі", + "ja": "Đ¶Đ°ĐżĐŸĐœ тілі", + "ka-GE": "ĐłŃ€ŃƒĐ·ĐžĐœ тілі", + "kk-KZ": "Ò›Đ°Đ·Đ°Ò› тілі", + "km-KH": "ĐșŃ…ĐŒĐ”Ń€ тілі", + "kn-IN": "ĐșĐ°ĐœĐœĐ°ĐŽĐ° тілі", + "ko": "Đșәріс тілі", + "ky-KG": "Ò›Ń‹Ń€Ò“Ń‹Đ· тілі", + "lt-LT": "лОтĐČа тілі", + "lv-LV": "Đ»Đ°Ń‚Ń‹Ńˆ тілі", + "mk-MK": "ĐŒĐ°ĐșĐ”ĐŽĐŸĐœĐžŃĐ»Ń‹Ò› тіл", + "ml-IN": "ĐŒĐ°Đ»Đ°ŃĐ»Đ°ĐŒ тілі", + "mr-IN": "ĐŒĐ°Ń€Đ°Ń‚Đž тілі", + "ms": "ĐŒĐ°Đ»Đ°Đč тілі", + "my": "Đ±ĐžŃ€ĐŒĐ° тілі", + "nb": "ĐœĐŸŃ€ĐČДг тілі", + "nl": "ĐłĐŸĐ»Đ»Đ°ĐœĐŽ тілі", + "pa-IN": "ĐżĐ”ĐœĐŽĐ¶Đ°Đ±Đž тілі", + "pl": "ĐżĐŸĐ»ŃĐș тілі", + "pt-BR": "Đ±Ń€Đ°Đ·ĐžĐ»ĐžŃĐ»Ń‹Ò› ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ» тілі", + "pt-PT": "Đ”ŃƒŃ€ĐŸĐżĐ°Đ»Ń‹Ò› ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ» тілі", + "ro-RO": "Ń€ŃƒĐŒŃ‹Đœ тілі", + "ru": "ĐŸŃ€Ń‹Ń тілі", + "sk-SK": "ŃĐ»ĐŸĐČаĐș тілі", + "sl-SI": "ŃĐ»ĐŸĐČĐ”Đœ тілі", + "sq-AL": "Đ°Đ»Đ±Đ°Đœ тілі", + "sr": "сДрб тілі", + "sv": "шĐČДЎ тіілі", + "sw": "ŃŃƒĐ°Ń…ĐžĐ»Đž тілі", + "ta-IN": "Ń‚Đ°ĐŒĐžĐ»ŃŒ тілі", + "te-IN": "Ń‚Đ”Đ»ŃƒĐłŃƒ тілі", + "th": "таĐč тілі", + "tl-PH": "Ń„ĐžĐ»ĐžĐżĐżĐžĐœ тілі", + "tr": "Ń‚ÒŻŃ€Ń–Đș тілі", + "ug": "Ò±ĐčÒ“Ń‹Ń€ тілі", + "uk-UA": "уĐșŃ€Đ°ĐžĐœ тілі", + "ur": "урЮу тілі", + "vi": "ĐČŃŒĐ”Ń‚ĐœĐ°ĐŒ тілі", + "yue": "ĐșĐ°ĐœŃ‚ĐŸĐœ тілі", + "zh-CN": "Ò›Ń‹Ń‚Đ°Đč тілі (ÒšŃ‹Ń‚Đ°Đč)", + "zh-HK": "Ò›Ń‹Ń‚Đ°Đč тілі (Đ“ĐŸĐœĐșĐŸĐœĐł)", + "zh-Hant": "ĐŽÓ™ŃŃ‚ÒŻŃ€Đ»Ń– Ò›Ń‹Ń‚Đ°Đč тілі" + }, + "km-KH": { + "af-ZA": "ážąáž¶áž áŸ’ážšáŸ’ážœáž·áž€", + "ar": "ážąáž¶ážšáŸ‰áž¶áž”áŸ‹", + "az-AZ": "ážąáž¶ážŸáŸŠáŸ‚áž”áŸƒáž áŸ’ážŸáž„áŸ‹", + "bg-BG": "ប៊ុលហ្ការឞ", + "bn-BD": "បង់ក្លាដែស", + "bs-BA": "បឌស្ន៊ឞ", + "ca": "áž€áž¶ážáž¶ážĄáž¶áž“", + "cs": "ឆែក", + "da": "ដាណážșម៉ាក", + "de": "ážąáž¶áž›áŸ’áž›ážșម៉ង់", + "el": "ក្រិក", + "en": "ឱង់គ្លេស", + "es": "ážąáŸážŸáŸ’áž”áŸ‰áž¶áž‰", + "et-EE": "ážąáŸážŸáŸ’ážážŒáž“ážž", + "eu": "បាស", + "fa-IR": "ពែរ្ស", + "fi": "áž áŸ’ážœáž¶áŸ†áž„ážĄáž„áŸ‹", + "fr": "បារាំង", + "ga-IE": "ឱៀរឡង់", + "gl-ES": "ហ្គាលឞសៀន", + "gu-IN": "ហ្គឌចារ៉ាទឞ", + "he": "ហេប្រ៊ឌ", + "hi-IN": "ហិណ្ឌឌ", + "hr-HR": "áž€áŸ’ážšážŒážąáž¶ážŸáŸŠážž", + "hu": "ហុងគ្រឞ", + "id": "ងណ្ឌឌណេស៊ឞ", + "it": "ážąáŸŠážžážáž¶áž›ážž", + "ja": "ជប៉ុន", + "ka-GE": "ហ្សកហ្ស៊ើ", + "kk-KZ": "កាហ្សាក់ស្ថាន", + "km-KH": "ខ្មែរ", + "kn-IN": "ខាណាដា", + "ko": "កឌរ៉េ", + "ky-KG": "កៀហ្ស៊ឞស៊ឞស្ថាន", + "lt-LT": "លឞទុយឹានឞ", + "lv-LV": "ážĄáŸážážŒáž“ážž", + "mk-MK": "ម៉ាសេដ្វាន", + "ml-IN": "áž˜áŸ‰áž¶ážĄáž¶áž™áŸ‰áž¶ážĄáž¶áž˜", + "mr-IN": "ម៉ារ៉ាធឞ", + "ms": "áž˜áŸ‰áž¶ážĄáŸ", + "my": "ភឌមា", + "nb": "ន័រវែស", + "nl": "áž ážŒážĄáž„áŸ‹", + "pa-IN": "ពុនចាប៊ឞ", + "pl": "áž”áŸ‰ážŒážĄážŒáž‰", + "pt-BR": "ព័រទុយហ្គាល់ប្រេស៊ឞល", + "pt-PT": "áž–áŸážšáž‘áž»áž™áž áŸ’áž‚áž¶áž›áŸ‹ážąážșរ៉ុប", + "ro-RO": "រ៉ឌម៉ានឞ", + "ru": "រុស្ស៊ឞ", + "sk-SK": "ស្លឌវ៉ាគឞ", + "sl-SI": "ស្លឌវេនឞ", + "sq-AL": "ážąáž¶áž›áŸ‹áž”áž¶áž“ážž", + "sr": "ស៊ែប៊ើ", + "sv": "ážŸáŸŠáž»áž™ážąáŸ‚áž", + "sw": "ស្វាហ៊ឞលឞ", + "ta-IN": "តាមឞល", + "te-IN": "តេលឌហ្គឌ", + "th": "ថៃ", + "tl-PH": "ហ្វើលើពើន", + "tr": "តវកគឞ", + "ug": "ážąáŸŠáž»áž™áž áŸ’áž‚ážœ", + "uk-UA": "ážąáŸŠáž»áž™áž€áŸ’ážšáŸ‚áž“", + "ur": "ážąáŸŠážŒážšážŒážŒ", + "vi": "វៀតណាម", + "yue": "កាតាំង", + "zh-CN": "ចិន (ចិន)", + "zh-HK": "ចិន (ហុងកុង)", + "zh-Hant": "ចិនបុរាណ" + }, + "kn-IN": { + "af-ZA": "àȆàČ«àłàȰàČżàȕàČŸàČšàłàČžàł", + "ar": "àȅàČ°àł‡àČŹàČżàČ•àł", + "az-AZ": "àȅàČœàł†àČ°àłàČŹàłˆàȜàČŸàČšàČż", + "bg-BG": "àČŹàČČàłàČ—àł‡àȰàČżàČŻàČšàł", + "bn-BD": "àČŹàČŸàȂàČ—àłàČČàČŸ", + "bs-BA": "àČŹàł‹àČžàłàČšàČżàČŻàČšàł", + "ca": "àČ•àł†àȟàČČàČŸàČšàł", + "cs": "àČœàł†àČ•àł", + "da": "àČĄàłàČŻàČŸàČšàČżàČ¶àł", + "de": "àȜàČ°àłàČźàČšàł", + "el": "àČ—àłàČ°àł€àČ•àł", + "en": "àȇàȂàČ—àłàČČàČżàČ·àł", + "es": "àČžàłàČȘàłàČŻàČŸàČšàČżàČ·àł", + "et-EE": "àȎàČžàłàČŸàłŠàČšàČżàČŻàČšàł", + "eu": "àČŹàČŸàČžàłàČ•àł", + "fa-IR": "àČȘàČ°àłàȶàČżàČŻàČšàł", + "fi": "àČ«àČżàČšàłàČšàČżàČ¶àł", + "fr": "àČ«àłàČ°àł†àȂàČšàł", + "ga-IE": "àȐàȰàČżàČ·àł", + "gl-ES": "àČ—àłàČŻàČŸàČČàČżàȶàČżàČŻàČšàł", + "gu-IN": "àČ—àłàȜàȰàČŸàČ€àČż", + "he": "àČčàł€àČŹàłàČ°àł‚", + "hi-IN": "àČčàČżàȂàČŠàČż", + "hr-HR": "àČ•àłàČ°àłŠàČŻàł‡àȶàČżàČŻàČšàł", + "hu": "àČčàȂàČ—àł‡àȰàČżàČŻàČšàł", + "id": "àȇàȂàČĄàł‹àČšàł‡àȶàČżàČŻàČšàł", + "it": "àȇàȟàČŸàČČàČżàČŻàČšàł", + "ja": "àȜàČŸàČȘàČšàł€àČžàł", + "ka-GE": "àȜàČŸàČ°àłàȜàČżàČŻàČšàł", + "kk-KZ": "àȕàȝàČ•àł", + "km-KH": "àȖàČźàł‡àČ°àł", + "kn-IN": "àȕàČšàłàČšàČĄ", + "ko": "àČ•àłŠàȰàČżàČŻàČšàł", + "ky-KG": "àȕàČżàČ°àłàȗàČżàČœàł", + "lt-LT": "àČČàČżàČ„àłàČ”àł‡àČšàČżàČŻàČšàł", + "lv-LV": "àČČàČŸàČŸàłàČ”àČżàČŻàČšàł", + "mk-MK": "àČźàł†àČžàČżàČĄàł‹àČšàČżàČŻàČšàł", + "ml-IN": "àČźàČČàČŻàČŸàČłàȂ", + "mr-IN": "àČźàȰàČŸàČ àČż", + "ms": "àČźàČČàČŻàł", + "my": "àČŹàČ°àłàČźàł€àČžàł", + "nb": "àČšàČŸàČ°àłàČ”àł†àȜàČżàČŻàČšàł àČŹàłŠàČ•àłàČźàČČàł", + "nl": "àČĄàČšàł", + "pa-IN": "àČȘàȂàȜàČŸàČŹàČż", + "pl": "àČȘàłŠàČČàČżàČ¶àł", + "pt-BR": "àČŹàłàČ°àł†àȜàČżàČČàČżàČŻàČšàł àČȘàł‹àČ°àłàČšàłàČ—àł€àČžàł", + "pt-PT": "àČŻàł‚àČ°àł‹àČȘàČżàČŻàČšàł àČȘàł‹àČ°àłàČšàłàČ—àł€àČžàł", + "ro-RO": "àČ°àłŠàČźàł‡àČšàČżàČŻàČšàł", + "ru": "àȰàČ·àłàČŻàČšàł", + "sk-SK": "àČžàłàČČàł‹àČ”àČŸàČ•àł", + "sl-SI": "àČžàłàČČàł‹àČ”àł‡àČšàČżàČŻàČšàł", + "sq-AL": "àȅàČČàłàČŹàł‡àČšàČżàČŻàČšàł", + "sr": "àČžàł†àČ°àłàČŹàČżàČŻàČšàł", + "sv": "àČžàłàČ”àł€àČĄàČżàČ·àł", + "sw": "àČžàłàČ”àČčàČżàČČàČż", + "ta-IN": "àČ€àČźàČżàČłàł", + "te-IN": "àČ€àł†àČČàłàČ—àł", + "th": "àČ„àČŸàČŻàł", + "tl-PH": "àČ«àČżàČČàČżàČȘàČżàČšàłŠ", + "tr": "àȟàČ°àłàȕàČżàČ¶àł", + "ug": "àȉàČŻàČżàȘàČ°àł", + "uk-UA": "àȉàČ•àłàČ°àł‡àČšàČżàČŻàČšàł", + "ur": "àȉàČ°àłàČŠàł", + "vi": "àČ”àČżàČŻàł†àČŸàłàČšàČŸàČźàł€àČžàł", + "yue": "àČ•àłàČŻàČŸàȂàȟàČšàł€àČžàł", + "zh-CN": "àČšàłˆàČšàł€àČžàł (àČšàł€àČšàČŸ)", + "zh-HK": "àČšàłˆàČšàł€àČžàł (àČčàČŸàȂàČ—àł àȕàČŸàȂàČ—àł)", + "zh-Hant": "àČžàČŸàȂàČȘàłàȰàČŠàČŸàČŻàČżàȕ àČšàłˆàČšàł€àČžàł" + }, + "ko": { + "af-ZA": "ì•„í”„ëŠŹìčžìŠ€ì–Ž", + "ar": "아랍얎", + "az-AZ": "아제넎바읎잔얎", + "bg-BG": "ë¶ˆê°€ëŠŹì•„ì–Ž", + "bn-BD": "ëČ”êłšì–Ž", + "bs-BA": "ëłŽìŠ€ë‹ˆì•„ì–Ž", + "ca": "ìčŽíƒˆëĄœë‹ˆì•„ì–Ž", + "cs": "ìČŽìœ”ì–Ž", + "da": "ëŽë§ˆíŹì–Ž", + "de": "독음얎", + "el": "ê·žëŠŹìŠ€ì–Ž", + "en": "영얎", + "es": "슀페읞얎", + "et-EE": "에슀토니아얎", + "eu": "ë°”ìŠ€íŹì–Ž", + "fa-IR": "페넎시아얎", + "fi": "핀란드얎", + "fr": "프랑슀얎", + "ga-IE": "아음랜드얎", + "gl-ES": "ê°ˆëŠŹì‹œì•„ì–Ž", + "gu-IN": "ê”ŹìžëŒíŠžì–Ž", + "he": "ížˆëžŒëŠŹì–Ž", + "hi-IN": "힌디얎", + "hr-HR": "íŹëĄœì•„í‹°ì•„ì–Ž", + "hu": "í—ê°€ëŠŹì–Ž", + "id": "읞도넀시아얎", + "it": "ìŽíƒˆëŠŹì•„ì–Ž", + "ja": "ìŒëłžì–Ž", + "ka-GE": "ìĄ°ì§€ì•„ì–Ž", + "kk-KZ": "ìčŽìžíì–Ž", + "km-KH": "íŹë©”ë„Žì–Ž", + "kn-IN": "ìčžë‚˜ë‹€ì–Ž", + "ko": "한ꔭ얎", + "ky-KG": "킀넎Ʞ슀얎", + "lt-LT": "ëŠŹíˆŹì•„ë‹ˆì•„ì–Ž", + "lv-LV": "띌튞ëč„ì•„ì–Ž", + "mk-MK": "마쌀도니아얎", + "ml-IN": "말띌얄람얎", + "mr-IN": "마띌티얎", + "ms": "말레읎얎", + "my": "ëČ„ë§ˆì–Ž", + "nb": "녞넎웚읎얎", + "nl": "넀덜란드얎", + "pa-IN": "펀자람얎", + "pl": "폎란드얎", + "pt-BR": "íŹë„ŽíˆŹê°ˆì–Ž(람띌질)", + "pt-PT": "íŹë„ŽíˆŹê°ˆì–Ž(íŹë„ŽíˆŹê°ˆ)", + "ro-RO": "ëŁšë§ˆë‹ˆì•„ì–Ž", + "ru": "ëŸŹì‹œì•„ì–Ž", + "sk-SK": "ìŠŹëĄœë°”í‚€ì•„ì–Ž", + "sl-SI": "ìŠŹëĄœëČ ë‹ˆì•„ì–Ž", + "sq-AL": "알바니아얎", + "sr": "섞넎ëč„ì•„ì–Ž", + "sv": "슀웚덎얎", + "sw": "ìŠ€ì™€ížëŠŹì–Ž", + "ta-IN": "타밀얎", + "te-IN": "í…”ëŁšê”Źì–Ž", + "th": "태ꔭ얎", + "tl-PH": "í•„ëŠŹí•€ì–Ž", + "tr": "터킀얎", + "ug": "ìœ„ê”Źë„Žì–Ž", + "uk-UA": "ìš°íŹëŒìŽë‚˜ì–Ž", + "ur": "우넎두얎", + "vi": "ëČ íŠžë‚šì–Ž", + "yue": "ꎑ둄얎", + "zh-CN": "쀑ꔭ얎(쀑ꔭ)", + "zh-HK": "쀑ꔭ얎(홍윩)", + "zh-Hant": "쀑ꔭ얎(ëȈìČŽ)" + }, + "ky-KG": { + "af-ZA": "афроĐșĐ°Đ°ĐœŃ", + "ar": "араб тОлО", + "az-AZ": "азДрбаĐčĐ¶Đ°ĐœŃ‡Đ°", + "bg-BG": "Đ±ĐŸĐ»ĐłĐ°Ń€Ń‡Đ°", + "bn-BD": "Đ±Đ”ĐœĐłĐ°Đ»Ń‡Đ°", + "bs-BA": "Đ±ĐŸŃĐœĐžŃŃ‡Đ°", + "ca": "ĐșĐ°Ń‚Đ°Đ»Đ°ĐœŃ‡Đ°", + "cs": "чДхчД", + "da": "Юатча", + "de": "ĐœĐ”ĐŒĐžŃŃ‡Đ”", + "el": "грДĐșчД", + "en": "Đ°ĐœĐłĐ»ĐžŃŃ‡Đ”", + "es": "ĐžŃĐżĐ°ĐœŃ‡Đ°", + "et-EE": "ŃŃŃ‚ĐŸĐœŃ‡ĐŸ", + "eu": "басĐșча", + "fa-IR": "пДрсОЎчД", + "fi": "Ń„ĐžĐœŃ‡Đ”", + "fr": "Ń„Ń€Đ°ĐœŃ†ŃƒĐ·Ń‡Đ°", + "ga-IE": "ĐžŃ€Đ»Đ°ĐœĐŽŃ‡Đ°", + "gl-ES": "галОсчД", + "gu-IN": "ĐłŃƒĐŽĐ¶Đ°Ń€Đ°Ń‚Đž", + "he": "ĐžĐČрот", + "hi-IN": "Ń…ĐžĐœĐŽĐž", + "hr-HR": "Ń…ĐŸŃ€ĐČатча", + "hu": "ĐČĐ”ĐœĐłĐ”Ń€Ń‡Đ”", + "id": "ĐžĐœĐŽĐŸĐœĐ”Đ·ĐžŃŃ‡Đ°", + "it": "ĐžŃ‚Đ°Đ»ĐžŃĐœŃ‡Đ°", + "ja": "Đ¶Đ°ĐżĐŸĐœŃ‡ĐŸ", + "ka-GE": "ĐłŃ€ŃƒĐ·ĐžĐœŃ‡Đ”", + "kk-KZ": "ĐșазаĐșча", + "km-KH": "ĐșŃ…ĐŒĐ”Ń€Ń‡Đ”", + "kn-IN": "ĐșĐ°ĐœĐœĐ°ĐŽĐ°", + "ko": "ĐșĐŸŃ€Đ”ĐčчД", + "ky-KG": "Đșыргызча", + "lt-LT": "Đ»ĐžŃ‚ĐŸĐČŃ‡ĐŸ", + "lv-LV": "Đ»Đ°Ń‚Ń‹ŃˆŃ‡Đ°", + "mk-MK": "ĐŒĐ°ĐșĐ”ĐŽĐŸĐœŃ‡ĐŸ", + "ml-IN": "ĐŒĐ°Đ»Đ°ŃĐ»Đ°ĐŒŃ‡Đ°", + "mr-IN": "ĐŒĐ°Ń€Đ°Ń‚Ń…ĐžŃ‡Đ”", + "ms": "ĐŒĐ°Đ»Đ°Đčча", + "my": "Đ±ĐžŃ€ĐŒĐ°ĐœŃ‡Đ°", + "nb": "ĐœĐŸŃ€ĐČĐ”ĐłĐžŃĐ»Ń‹Đș буĐșĐŒĐŸĐ»Ń‡ĐŸ", + "nl": "ĐœĐžĐŽĐ”Ń€Đ»Đ°ĐœĐŽŃ‡Đ°", + "pa-IN": "ĐżĐ°ĐœĐŽĐ¶Đ°Đ±ĐžŃ‡Đ”", + "pl": "ĐżĐŸĐ»ŃŒŃˆĐ°Đ»Ń‹Đșча", + "pt-BR": "Đ±Ń€Đ°Đ·ĐžĐ»ĐžŃĐ»Ń‹Đș ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»Ń‡Đ°", + "pt-PT": "Đ”ĐČŃ€ĐŸĐżĐ°Đ»Ń‹Đș ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»Ń‡Đ°", + "ro-RO": "Ń€ŃƒĐŒŃ‹ĐœŃ‡Đ°", + "ru": "ĐŸŃ€ŃƒŃŃ‡Đ°", + "sk-SK": "ŃĐ»ĐŸĐČаĐșча", + "sl-SI": "ŃĐ»ĐŸĐČĐ”ĐœŃ‡Đ”", + "sq-AL": "Đ°Đ»Đ±Đ°ĐœŃ‡Đ°", + "sr": "сДрбчД", + "sv": "шĐČДЎчД", + "sw": "ŃŃƒĐ°Ń…ĐžĐ»ĐžŃ‡Đ”", + "ta-IN": "Ń‚Đ°ĐŒĐžĐ»Ń‡Đ”", + "te-IN": "Ń‚Đ”Đ»ŃƒĐłŃƒŃ‡Đ°", + "th": "таĐčча", + "tl-PH": "Ń„ĐžĐ»ĐžĐżĐżĐžĐœŃ‡Đ”", + "tr": "Ń‚ÒŻŃ€Đșчө", + "ug": "уĐčгурча", + "uk-UA": "уĐșŃ€Đ°ĐžĐœŃ‡Đ”", + "ur": "урЮуча", + "vi": "ĐČŃŒĐ”Ń‚ĐœĐ°ĐŒŃ‡Đ°", + "yue": "ĐșĐ°ĐœŃ‚ĐŸĐœŃ‡ĐŸ", + "zh-CN": "ĐșытаĐčча (КытаĐč)", + "zh-HK": "ĐșытаĐčча (Đ“ĐŸĐœĐșĐŸĐœĐł)", + "zh-Hant": "ĐșытаĐčча (ŃĐ°Đ»Ń‚Ń‚ŃƒŃƒ жазуу)" + }, + "lt-LT": { + "af-ZA": "afrikanĆł", + "ar": "arabĆł", + "az-AZ": "azerbaidĆŸaniečiĆł", + "bg-BG": "bulgarĆł", + "bn-BD": "bengalĆł", + "bs-BA": "bosniĆł", + "ca": "katalonĆł", + "cs": "čekĆł", + "da": "danĆł", + "de": "vokiečiĆł", + "el": "graikĆł", + "en": "anglĆł", + "es": "ispanĆł", + "et-EE": "estĆł", + "eu": "baskĆł", + "fa-IR": "persĆł", + "fi": "suomiĆł", + "fr": "prancĆ«zĆł", + "ga-IE": "airiĆł", + "gl-ES": "galisĆł", + "gu-IN": "gudĆŸaratĆł", + "he": "hebrajĆł", + "hi-IN": "hindi", + "hr-HR": "kroatĆł", + "hu": "vengrĆł", + "id": "indoneziečiĆł", + "it": "italĆł", + "ja": "japonĆł", + "ka-GE": "gruzinĆł", + "kk-KZ": "kazachĆł", + "km-KH": "khmerĆł", + "kn-IN": "kanadĆł", + "ko": "korėjiečiĆł", + "ky-KG": "kirgizĆł", + "lt-LT": "lietuviĆł", + "lv-LV": "latviĆł", + "mk-MK": "makedonĆł", + "ml-IN": "malajaliĆł", + "mr-IN": "maratĆł", + "ms": "malajiečiĆł", + "my": "birmiečiĆł", + "nb": "norvegĆł bukmolas", + "nl": "olandĆł", + "pa-IN": "pandĆŸabĆł", + "pl": "lenkĆł", + "pt-BR": "portugalĆł (Brazilija)", + "pt-PT": "portugalĆł (Portugalija)", + "ro-RO": "rumunĆł", + "ru": "rusĆł", + "sk-SK": "slovakĆł", + "sl-SI": "slovėnĆł", + "sq-AL": "albanĆł", + "sr": "serbĆł", + "sv": "ĆĄvedĆł", + "sw": "suahiliĆł", + "ta-IN": "tamilĆł", + "te-IN": "telugĆł", + "th": "tajĆł", + "tl-PH": "filipiniečiĆł", + "tr": "turkĆł", + "ug": "uigĆ«rĆł", + "uk-UA": "ukrainiečiĆł", + "ur": "urdu", + "vi": "vietnamiečiĆł", + "yue": "kinĆł (Kantono tarmė)", + "zh-CN": "kinĆł (Kinija)", + "zh-HK": "kinĆł (Honkongas)", + "zh-Hant": "kinĆł (tradicinė)" + }, + "lv-LV": { + "af-ZA": "afrikandu", + "ar": "arābu", + "az-AZ": "azerbaidĆŸÄĆ†u", + "bg-BG": "bulgāru", + "bn-BD": "bengāČu", + "bs-BA": "bosnieĆĄu", + "ca": "katalāƆu", + "cs": "čehu", + "da": "dāƆu", + "de": "vācu", + "el": "grieÄ·u", + "en": "angÄŒu", + "es": "spāƆu", + "et-EE": "igauƆu", + "eu": "basku", + "fa-IR": "persieĆĄu", + "fi": "somu", + "fr": "franču", + "ga-IE": "Ä«ru", + "gl-ES": "galisieĆĄu", + "gu-IN": "gudĆŸaratu", + "he": "ivrits", + "hi-IN": "hindi", + "hr-HR": "horvātu", + "hu": "ungāru", + "id": "indonēzieĆĄu", + "it": "itāČu", + "ja": "japāƆu", + "ka-GE": "gruzÄ«nu", + "kk-KZ": "kazahu", + "km-KH": "khmeru", + "kn-IN": "kannadu", + "ko": "korejieĆĄu", + "ky-KG": "kirgÄ«zu", + "lt-LT": "lietuvieĆĄu", + "lv-LV": "latvieĆĄu", + "mk-MK": "maÄ·edonieĆĄu", + "ml-IN": "malajalu", + "mr-IN": "marathu", + "ms": "malajieĆĄu", + "my": "birmieĆĄu", + "nb": "norvēģu bukmols", + "nl": "holandieĆĄu", + "pa-IN": "pandĆŸabu", + "pl": "poÄŒu", + "pt-BR": "portugāČu (BrazÄ«lija)", + "pt-PT": "portugāČu (Portugāle)", + "ro-RO": "rumāƆu", + "ru": "krievu", + "sk-SK": "slovāku", + "sl-SI": "slovēƆu", + "sq-AL": "albāƆu", + "sr": "serbu", + "sv": "zviedru", + "sw": "svahili", + "ta-IN": "tamilu", + "te-IN": "telugu", + "th": "taju", + "tl-PH": "filipÄ«nieĆĄu", + "tr": "turku", + "ug": "uiguru", + "uk-UA": "ukraiƆu", + "ur": "urdu", + "vi": "vjetnamieĆĄu", + "yue": "kantonieĆĄu", + "zh-CN": "Ä·Ä«nieĆĄu (Ķīna)", + "zh-HK": "Ä·Ä«nieĆĄu (Honkonga)", + "zh-Hant": "Ä·Ä«nieĆĄu tradicionālā" + }, + "mk-MK": { + "af-ZA": "афроĐșĐ°ĐœŃ", + "ar": "арапсĐșĐž", + "az-AZ": "Đ°Đ·Đ”Ń€Đ±Đ”Ń˜ŃŸĐ°ĐœŃĐșĐž", + "bg-BG": "Đ±ŃƒĐłĐ°Ń€ŃĐșĐž", + "bn-BD": "Đ±Đ”ĐœĐłĐ°Đ»ŃĐșĐž", + "bs-BA": "Đ±ĐŸŃĐ°ĐœŃĐșĐž", + "ca": "ĐșĐ°Ń‚Đ°Đ»ĐŸĐœŃĐșĐž", + "cs": "Ń‡Đ”ŃˆĐșĐž", + "da": "ĐŽĐ°ĐœŃĐșĐž", + "de": "ĐłĐ”Ń€ĐŒĐ°ĐœŃĐșĐž", + "el": "грчĐșĐž", + "en": "Đ°ĐœĐłĐ»ĐžŃĐșĐž", + "es": "ŃˆĐżĐ°ĐœŃĐșĐž", + "et-EE": "Đ”ŃŃ‚ĐŸĐœŃĐșĐž", + "eu": "басĐșОсĐșĐž", + "fa-IR": "пДрсОсĐșĐž", + "fi": "Ń„ĐžĐœŃĐșĐž", + "fr": "Ń„Ń€Đ°ĐœŃ†ŃƒŃĐșĐž", + "ga-IE": "орсĐșĐž", + "gl-ES": "галОцОсĐșĐž", + "gu-IN": "гуџаратсĐșĐž", + "he": "Ń…Đ”Đ±Ń€Đ”Ń˜ŃĐșĐž", + "hi-IN": "Ń…ĐžĐœĐŽĐž", + "hr-HR": "хрĐČатсĐșĐž", + "hu": "ŃƒĐœĐłĐ°Ń€ŃĐșĐž", + "id": "ĐžĐœĐŽĐŸĐœĐ”Đ·ĐžŃĐșĐž", + "it": "ĐžŃ‚Đ°Đ»ĐžŃ˜Đ°ĐœŃĐșĐž", + "ja": "Ń˜Đ°ĐżĐŸĐœŃĐșĐž", + "ka-GE": "ĐłŃ€ŃƒĐ·ĐžŃ˜ŃĐșĐž", + "kk-KZ": "ĐșĐ°Đ·Đ°Ń…ŃŃ‚Đ°ĐœŃĐșĐž", + "km-KH": "ĐșĐŒĐ”Ń€ŃĐșĐž", + "kn-IN": "ĐșĐ°ĐœĐ°ĐŽŃĐșĐž", + "ko": "ĐșĐŸŃ€Đ”Ń˜ŃĐșĐž", + "ky-KG": "ĐșоргосĐșĐž", + "lt-LT": "лОтĐČĐ°ĐœŃĐșĐž", + "lv-LV": "Đ»Đ”Ń‚ĐŸĐœŃĐșĐž", + "mk-MK": "ĐŒĐ°ĐșĐ”ĐŽĐŸĐœŃĐșĐž", + "ml-IN": "ĐŒĐ°Đ»Đ°Ń˜Đ°Đ»Đ°ĐŒŃĐșĐž", + "mr-IN": "ĐŒĐ°Ń€Đ°Ń‚ŃĐșĐž", + "ms": "ĐŒĐ°Đ»Đ°Ń˜ŃĐșĐž", + "my": "Đ±ŃƒŃ€ĐŒĐ°ĐœŃĐșĐž", + "nb": "ĐœĐŸŃ€ĐČДшĐșĐž (буĐșĐŒĐŸĐ»)", + "nl": "Ń…ĐŸĐ»Đ°ĐœĐŽŃĐșĐž", + "pa-IN": "ĐżĐ”ĐœŃŸĐ°ĐżŃĐșĐž", + "pl": "ĐżĐŸĐ»ŃĐșĐž", + "pt-BR": "бразОлсĐșĐž ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃĐșĐž", + "pt-PT": "ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃĐșĐž", + "ro-RO": "Ń€ĐŸĐŒĐ°ĐœŃĐșĐž", + "ru": "русĐșĐž", + "sk-SK": "ŃĐ»ĐŸĐČачĐșĐž", + "sl-SI": "ŃĐ»ĐŸĐČĐ”ĐœĐ”Ń‡ĐșĐž", + "sq-AL": "Đ°Đ»Đ±Đ°ĐœŃĐșĐž", + "sr": "српсĐșĐž", + "sv": "шĐČДЎсĐșĐž", + "sw": "сĐČахОлсĐșĐž", + "ta-IN": "Ń‚Đ°ĐŒĐžĐ»ŃĐșĐž", + "te-IN": "Ń‚Đ”Đ»ŃƒĐłŃƒ", + "th": "Ń‚Đ°Ń˜Đ»Đ°ĐœĐŽŃĐșĐž", + "tl-PH": "Ń„ĐžĐ»ĐžĐżĐžĐœŃĐșĐž", + "tr": "турсĐșĐž", + "ug": "ујгурсĐșĐž", + "uk-UA": "уĐșŃ€Đ°ĐžĐœŃĐșĐž", + "ur": "урЮу", + "vi": "ĐČĐžĐ”Ń‚ĐœĐ°ĐŒŃĐșĐž", + "yue": "ĐșĐ°ĐœŃ‚ĐŸĐœŃĐșĐž", + "zh-CN": "ĐșĐžĐœĐ”ŃĐșĐž (ĐšĐžĐœĐ°)", + "zh-HK": "ĐșĐžĐœĐ”ŃĐșĐž (Đ„ĐŸĐœĐł ĐšĐŸĐœĐł)", + "zh-Hant": "Ń‚Ń€Đ°ĐŽĐžŃ†ĐžĐŸĐœĐ°Đ»Đ”Đœ ĐșĐžĐœĐ”ŃĐșĐž" + }, + "ml-IN": { + "af-ZA": "àŽ†àŽ«à”àŽ°àŽżàŽ•à”àŽ•àŽŸà”»àŽžà”", + "ar": "àŽ…àŽ±àŽŹàŽżàŽ•à”", + "az-AZ": "àŽ…àŽžà”ŒàŽŹà”ˆàŽœàŽŸàŽšàŽż", + "bg-BG": "àŽŹà”ŸàŽ—à”‡àŽ±àŽżàŽŻà”»", + "bn-BD": "àŽŹàŽ‚àŽ—à”àŽČàŽŸ", + "bs-BA": "àŽŹà”‹àŽžà”àŽšàŽżàŽŻà”»", + "ca": "àŽ•àŽ±à”àŽ±àŽŸàŽČàŽŸà”»", + "cs": "àŽšà”†àŽ•à”àŽ•à”", + "da": "àŽĄàŽŸàŽšàŽżàŽ·à”", + "de": "àŽœà”ŒàŽźà”àŽźà”»", + "el": "àŽ—à”àŽ°à”€àŽ•à”àŽ•à”", + "en": "àŽ‡àŽ‚àŽ—à”àŽČà”€àŽ·à”", + "es": "àŽžà”â€ŒàŽȘàŽŸàŽšàŽżàŽ·à”", + "et-EE": "àŽŽàŽžà”àŽ±à”àŽ±à”‹àŽŁàŽżàŽŻà”»", + "eu": "àŽŹàŽŸàŽžà”â€ŒàŽ•à”", + "fa-IR": "àŽȘà”‡à”ŒàŽ·à”àŽŻà”»", + "fi": "àŽ«àŽżàŽšà”àŽšàŽżàŽ·à”", + "fr": "àŽ«à”àŽ°àŽžà”àŽšà”", + "ga-IE": "àŽàŽ±àŽżàŽ·à”", + "gl-ES": "àŽ—àŽČà”€àŽ·à”àŽŻà”»", + "gu-IN": "àŽ—à”àŽœàŽ±àŽŸàŽ€à”àŽ€àŽż", + "he": "àŽčà”€àŽŹà”àŽ°à”", + "hi-IN": "àŽčàŽżàŽšà”àŽŠàŽż", + "hr-HR": "àŽ•à”àŽ°à”ŠàŽŻà”‡àŽ·à”àŽŻà”»", + "hu": "àŽčàŽ‚àŽ—à”‡àŽ±àŽżàŽŻà”»", + "id": "àŽ‡àŽšà”àŽ€à”‹àŽšà”‡àŽ·à”àŽŻà”»", + "it": "àŽ‡àŽ±à”àŽ±àŽŸàŽČàŽżàŽŻà”»", + "ja": "àŽœàŽŸàŽȘà”àŽȘàŽšà”€àŽžà”", + "ka-GE": "àŽœà”‹à”ŒàŽœàŽżàŽŻà”»", + "kk-KZ": "àŽ•àŽžàŽŸàŽ–à”", + "km-KH": "àŽ–àŽźà”†à”Œ", + "kn-IN": "àŽ•àŽšà”àŽšàŽĄ", + "ko": "àŽ•à”ŠàŽ±àŽżàŽŻà”»", + "ky-KG": "àŽ•àŽżà”ŒàŽ—àŽżàŽžà”", + "lt-LT": "àŽČàŽżàŽ€à”àŽ”àŽŸàŽšàŽżàŽŻà”»", + "lv-LV": "àŽČàŽŸàŽ±à”àŽ±à”àŽ”àŽżàŽŻà”»", + "mk-MK": "àŽźàŽŸàŽžàŽżàŽĄà”‹àŽŁàŽżàŽŻà”»", + "ml-IN": "àŽźàŽČàŽŻàŽŸàŽłàŽ‚", + "mr-IN": "àŽźàŽ±àŽŸàŽ€à”àŽ€àŽż", + "ms": "àŽźàŽČà”†àŽŻà”", + "my": "àŽŹà”ŒàŽźà”€àŽžà”", + "nb": "àŽšà”‹à”ŒàŽ”à”€àŽœàŽżàŽŻà”» àŽŹà”àŽ•à”â€ŒàŽźà”œ", + "nl": "àŽĄàŽšà”àŽšà”", + "pa-IN": "àŽȘàŽžà”àŽšàŽŸàŽŹàŽż", + "pl": "àŽȘà”‹àŽłàŽżàŽ·à”", + "pt-BR": "àŽŹà”àŽ°àŽžà”€àŽČàŽżàŽŻà”» àŽȘà”‹à”ŒàŽšà”àŽšà”àŽ—à”€àŽžà”", + "pt-PT": "àŽŻà”‚àŽ±à”‹àŽȘà”àŽŻà”» àŽȘà”‹à”ŒàŽšà”àŽšà”àŽ—à”€àŽžà”", + "ro-RO": "àŽ±à”ŠàŽźàŽŸàŽšàŽżàŽŻà”»", + "ru": "àŽ±àŽ·à”àŽŻà”»", + "sk-SK": "àŽžà”àŽČà”‹àŽ”àŽŸàŽ•à”", + "sl-SI": "àŽžà”àŽČà”‹àŽ”à”‡àŽšàŽżàŽŻà”»", + "sq-AL": "àŽ…à”œàŽŹà”‡àŽšàŽżàŽŻà”»", + "sr": "àŽžà”†à”ŒàŽŹàŽżàŽŻà”»", + "sv": "àŽžà”àŽ”à”€àŽĄàŽżàŽ·à”", + "sw": "àŽžà”àŽ”àŽŸàŽčàŽżàŽČàŽż", + "ta-IN": "àŽ€àŽźàŽżàŽŽà”", + "te-IN": "àŽ€à”†àŽČà”àŽ™à”àŽ•à”", + "th": "àŽ€àŽŸàŽŻà”", + "tl-PH": "àŽ«àŽżàŽČàŽżàŽȘà”àŽȘàŽżàŽšà”‹", + "tr": "àŽŸà”ŒàŽ•à”àŽ•àŽżàŽ·à”", + "ug": "àŽ‰àŽŻà”àŽ˜à”à”Œ", + "uk-UA": "àŽ‰àŽ•à”àŽ°à”‡àŽšàŽżàŽŻà”»", + "ur": "àŽ‰àŽ±à”àŽŠà”", + "vi": "àŽ”àŽżàŽŻàŽ±à”àŽ±à”àŽšàŽŸàŽźà”€àŽžà”", + "yue": "àŽ•àŽŸàŽšà”àŽ±àŽŁà”€àŽžà”", + "zh-CN": "àŽšà”ˆàŽšà”€àŽžà” (àŽšà”ˆàŽš)", + "zh-HK": "àŽšà”ˆàŽšà”€àŽžà” (àŽčà”‹àŽ™à”àŽ•à”‹àŽ™à”)", + "zh-Hant": "àŽȘàŽ°àŽźà”àŽȘàŽ°àŽŸàŽ—àŽ€ àŽšà”ˆàŽšà”€àŽžà”" + }, + "mr-IN": { + "af-ZA": "à€…à€«à„à€°à€żà€•à€Ÿà€šà„à€ž", + "ar": "à€…à€°à€Źà„€", + "az-AZ": "à€…à€à€°à€Źà„ˆà€œà€Ÿà€šà„€", + "bg-BG": "à€Źà€Čà„à€—à„‡à€°à€żà€Żà€š", + "bn-BD": "à€Źà€‚à€—à€Ÿà€Čà„€", + "bs-BA": "à€Źà„‹à€žà„à€šà€żà€Żà€š", + "ca": "à€•à€Ÿà€€à€Ÿà€Čà€Ÿà€š", + "cs": "à€à„‡à€•", + "da": "à€Ąà„…à€šà€żà€¶", + "de": "à€œà€°à„à€źà€š", + "el": "à€—à„à€°à„€à€•", + "en": "à€‡à€‚à€—à„à€°à€œà„€", + "es": "à€žà„à€Șà„…à€šà€żà€¶", + "et-EE": "à€‡à€žà„à€Ÿà„‹à€šà€żà€Żà€š", + "eu": "à€Źà€Ÿà€žà„à€•", + "fa-IR": "à€«à€Ÿà€°à€žà„€", + "fi": "à€«à€żà€šà„à€šà€żà€¶", + "fr": "à€«à„à€°à„‡à€‚à€š", + "ga-IE": "à€†à€Żà€°à€żà€¶", + "gl-ES": "à€—à„…à€Čà€żà€¶à€żà€Żà€š", + "gu-IN": "à€—à„à€œà€°à€Ÿà€€à„€", + "he": "à€čà€żà€Źà„à€°à„‚", + "hi-IN": "à€čà€żà€‚à€Šà„€", + "hr-HR": "à€•à„à€°à„‹à€à€¶à€żà€Żà€š", + "hu": "à€čà€‚à€—à„‡à€°à€żà€Żà€š", + "id": "à€‡à€‚à€Ąà„‹à€šà„‡à€¶à€żà€Żà€š", + "it": "à€‡à€Ÿà€Ÿà€Čà€żà€Żà€š", + "ja": "à€œà€Șà€Ÿà€šà„€", + "ka-GE": "à€œà„‰à€°à„à€œà€żà€Żà€š", + "kk-KZ": "à€•à€à€Ÿà€•", + "km-KH": "à€–à„à€źà„‡à€°", + "kn-IN": "à€•à€šà„à€šà€Ą", + "ko": "à€•à„‹à€°à€żà€Żà€š", + "ky-KG": "à€•à€żà€°à€—à„€à€", + "lt-LT": "à€Čà€żà€„à„à€†à€šà€żà€Żà€š", + "lv-LV": "à€Čà€Ÿà€€à„à€”à„à€čà€żà€Żà€š", + "mk-MK": "à€źà„…à€žà„‡à€Ąà„‹à€šà€żà€Żà€š", + "ml-IN": "à€źà€Čà„à€Żà€Ÿà€łà€ź", + "mr-IN": "à€źà€°à€Ÿà€ à„€", + "ms": "à€źà€Čà€Ż", + "my": "à€Źà€°à„à€źà„€", + "nb": "à€šà„‰à€°à„à€”à„‡à€œà€żà€Żà€š à€Źà„‹à€•à€źà€Ÿà€Č", + "nl": "à€Ąà€š", + "pa-IN": "à€Șà€‚à€œà€Ÿà€Źà„€", + "pl": "à€Șà„‹à€Čà€żà€¶", + "pt-BR": "à€Źà„à€°à€Ÿà€à€żà€Čà€żà€Żà€š à€Șà„‹à€°à„à€€à„à€—à„€à€œ", + "pt-PT": "à€Żà„à€°à„‹à€Șà€żà€Żà€š à€Șà„‹à€°à„à€€à„à€—à„€à€œ", + "ro-RO": "à€°à„‹à€źà€Ÿà€šà€żà€Żà€š", + "ru": "à€°à€¶à€żà€Żà€š", + "sk-SK": "à€žà„à€Čà„‹à€”à„à€čà€Ÿà€•", + "sl-SI": "à€žà„à€Čà„‹à€”à„à€čà„‡à€šà€żà€Żà€š", + "sq-AL": "à€…à€Čà„à€Źà€Ÿà€šà€żà€Żà€š", + "sr": "à€žà€°à„à€Źà€żà€Żà€š", + "sv": "à€žà„à€”à„€à€Ąà€żà€¶", + "sw": "à€žà„à€”à€Ÿà€čà€żà€Čà„€", + "ta-IN": "à€€à€Ÿà€źà€żà€ł", + "te-IN": "à€€à„‡à€Čà€—à„‚", + "th": "à€„à€Ÿà€ˆ", + "tl-PH": "à€«à€żà€Čà€żà€Șà€żà€šà„‹", + "tr": "à€€à„à€°à„à€•à„€", + "ug": "à€‰à€‡à€—à„à€°", + "uk-UA": "à€Żà„à€•à„à€°à„‡à€šà€żà€Żà€š", + "ur": "à€‰à€°à„à€Šà„‚", + "vi": "à€”à„à€čà€żà€à€€à€šà€Ÿà€źà„€", + "yue": "à€•à€à€Ÿà„‹à€šà„€à€œ", + "zh-CN": "à€šà„€à€šà„€ (à€šà„€à€š)", + "zh-HK": "à€šà„€à€šà„€ (à€čà€Ÿà€à€—à€•à€Ÿà€à€—)", + "zh-Hant": "à€Șà€Ÿà€°à€‚à€Șà€Ÿà€°à€żà€• à€šà„€à€šà„€" + }, + "ms": { + "af-ZA": "Afrikaans", + "ar": "Arab", + "az-AZ": "Azerbaijan", + "bg-BG": "Bulgaria", + "bn-BD": "Benggali", + "bs-BA": "Bosnia", + "ca": "Catalonia", + "cs": "Czech", + "da": "Denmark", + "de": "Jerman", + "el": "Greek", + "en": "Inggeris", + "es": "Sepanyol", + "et-EE": "Estonia", + "eu": "Basque", + "fa-IR": "Parsi", + "fi": "Finland", + "fr": "Perancis", + "ga-IE": "Ireland", + "gl-ES": "Galicia", + "gu-IN": "Gujerat", + "he": "Ibrani", + "hi-IN": "Hindi", + "hr-HR": "Croatia", + "hu": "Hungary", + "id": "Indonesia", + "it": "Itali", + "ja": "Jepun", + "ka-GE": "Georgia", + "kk-KZ": "Kazakhstan", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Korea", + "ky-KG": "Kirghiz", + "lt-LT": "Lithuania", + "lv-LV": "Latvia", + "mk-MK": "Macedonia", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Melayu", + "my": "Burma", + "nb": "Bokmal Norway", + "nl": "Belanda", + "pa-IN": "Punjabi", + "pl": "Poland", + "pt-BR": "Portugis Brazil", + "pt-PT": "Portugis Eropah", + "ro-RO": "Romania", + "ru": "Rusia", + "sk-SK": "Slovak", + "sl-SI": "Slovenia", + "sq-AL": "Albania", + "sr": "Serbia", + "sv": "Sweden", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "Filipina", + "tr": "Turki", + "ug": "Uyghur", + "uk-UA": "Ukraine", + "ur": "Urdu", + "vi": "Vietnam", + "yue": "Kantonis", + "zh-CN": "Cina (China)", + "zh-HK": "Cina (Hong Kong)", + "zh-Hant": "Cina Tradisional" + }, + "my": { + "af-ZA": "အာဖရိကနá€ș", + "ar": "အာရဗြ", + "az-AZ": "အဇာဘိုငá€șဂျနá€ș", + "bg-BG": "ဘူလá€șဂေသရဟသယနá€șှ", + "bn-BD": "ဘငá€șá€čဂလာှ", + "bs-BA": "á€˜á€±á€Źá€·á€…á€”á€źá€žá€šá€”á€șှ", + "ca": "ကတá€șတလနá€ș", + "cs": "ချကá€ș", + "da": "ဒိနá€șှမတá€ș", + "de": "ဂျဏမနá€ș", + "el": "ဂရိ", + "en": "အငá€șá€čဂလိပá€ș", + "es": "စပိနá€ș", + "et-EE": "အကá€șစတိုှနြှယာှ", + "eu": "ဘာစá€șခá€ș", + "fa-IR": "á€•á€«á€›á€Ÿá€Źá€ž", + "fi": "ဖငá€șလနá€ș", + "fr": "ပဌငá€șသစá€ș", + "ga-IE": "အိုငá€șှရစá€șရဟá€ș", + "gl-ES": "á€‚á€«á€œá€źá€…á€źá€šá€Ź", + "gu-IN": "ဂူဂျဏရဏတဟ", + "he": "ဟေဗဌá€Č", + "hi-IN": "ဟငá€șဒြ", + "hr-HR": "á€á€›á€­á€Żá€Ąá€±á€žá€›á€Ÿá€”á€șှ", + "hu": "ဟနá€șဂေရဟ", + "id": "အငá€șá€’á€­á€Żá€”á€źá€žá€›á€Ÿá€Źá€ž", + "it": "အြတာလြ", + "ja": "ဂျပနá€ș", + "ka-GE": "ဂျေဏá€șဂျဟယနá€ș", + "kk-KZ": "ကာဇကá€șခá€ș", + "km-KH": "ခမာ", + "kn-IN": "ကနá€șနဏဒါ", + "ko": "ကိုရြှယနá€șှ", + "ky-KG": "ကဏဂျစá€ș", + "lt-LT": "လစá€șသူယေသနဟသယဏသ", + "lv-LV": "လကá€șဗြယနá€ș", + "mk-MK": "မကá€șဆြဒိုှနြှယနá€șှ", + "ml-IN": "á€™á€Źá€œá€±á€šá€Źá€œá€™á€ș", + "mr-IN": "မာရသြ", + "ms": "မလေသ", + "my": "မဌနá€șမာ", + "nb": "နေဏá€șá€á€źá€‚á€»á€źá€šá€™á€ș ဘလတá€șခá€șá€™á€±á€Źá€œá€ș", + "nl": "ဒတá€șချá€ș", + "pa-IN": "ပနá€șချဏပဟ", + "pl": "ပိုလနá€ș", + "pt-BR": "ပေါá€șတူဂြ (ဘရာဇြှ)", + "pt-PT": "ပေါá€șတူဂြ (ငရေဏပ)", + "ro-RO": "ရိုမေသနဟသယဏသ", + "ru": "á€›á€Żá€›á€Ÿá€Źá€ž", + "sk-SK": "ဆလိုဗကá€ș", + "sl-SI": "á€†á€œá€­á€Żá€—á€±á€žá€”á€źá€žá€šá€Źá€ž", + "sq-AL": "အယá€șလá€șá€˜á€±á€žá€”á€źá€žá€šá€Źá€ž", + "sr": "ဆာှဘြှယာှ", + "sv": "á€†á€œá€źá€’á€„á€ș", + "sw": "á€†á€œá€Źá€Ÿá€źá€œá€ź", + "ta-IN": "တမြှလá€ș", + "te-IN": "တယá€șလူဂူ", + "th": "ထိုငá€șှ", + "tl-PH": "ဖိလစá€șပိုငá€ș", + "tr": "တူရကြ", + "ug": "á€á€źá€‚á€«", + "uk-UA": "ယူကရိနá€șှ", + "ur": "အူရဒူ", + "vi": "ဗြယကá€șနမá€ș", + "yue": "ကနá€șတုံ", + "zh-CN": "တရုတá€ș (ပဌညá€șမ)", + "zh-HK": "တရုတá€ș (á€Ÿá€±á€Źá€„á€șကေဏငá€ș)", + "zh-Hant": "á€›á€Ÿá€±á€žá€žá€Żá€¶á€žá€á€›á€Żá€á€ș" + }, + "nb": { + "af-ZA": "afrikaans", + "ar": "arabisk", + "az-AZ": "aserbajdsjansk", + "bg-BG": "bulgarsk", + "bn-BD": "bengali", + "bs-BA": "bosnisk", + "ca": "katalansk", + "cs": "tsjekkisk", + "da": "dansk", + "de": "tysk", + "el": "gresk", + "en": "engelsk", + "es": "spansk", + "et-EE": "estisk", + "eu": "baskisk", + "fa-IR": "persisk", + "fi": "finsk", + "fr": "fransk", + "ga-IE": "irsk", + "gl-ES": "galisisk", + "gu-IN": "gujarati", + "he": "hebraisk", + "hi-IN": "hindi", + "hr-HR": "kroatisk", + "hu": "ungarsk", + "id": "indonesisk", + "it": "italiensk", + "ja": "japansk", + "ka-GE": "georgisk", + "kk-KZ": "kasakhisk", + "km-KH": "khmer", + "kn-IN": "kannada", + "ko": "koreansk", + "ky-KG": "kirgisisk", + "lt-LT": "litauisk", + "lv-LV": "latvisk", + "mk-MK": "makedonsk", + "ml-IN": "malayalam", + "mr-IN": "marathi", + "ms": "malayisk", + "my": "burmesisk", + "nb": "norsk bokmĂ„l", + "nl": "nederlandsk", + "pa-IN": "panjabi", + "pl": "polsk", + "pt-BR": "portugisisk (Brasil)", + "pt-PT": "portugisisk (Portugal)", + "ro-RO": "rumensk", + "ru": "russisk", + "sk-SK": "slovakisk", + "sl-SI": "slovensk", + "sq-AL": "albansk", + "sr": "serbisk", + "sv": "svensk", + "sw": "swahili", + "ta-IN": "tamil", + "te-IN": "telugu", + "th": "thai", + "tl-PH": "filipino", + "tr": "tyrkisk", + "ug": "uigurisk", + "uk-UA": "ukrainsk", + "ur": "urdu", + "vi": "vietnamesisk", + "yue": "kantonesisk", + "zh-CN": "kinesisk (Kina)", + "zh-HK": "kinesisk (Hongkong)", + "zh-Hant": "kinesisk (tradisjonell)" + }, + "nl": { + "af-ZA": "Afrikaans", + "ar": "Arabisch", + "az-AZ": "Azerbeidzjaans", + "bg-BG": "Bulgaars", + "bn-BD": "Bengaals", + "bs-BA": "Bosnisch", + "ca": "Catalaans", + "cs": "Tsjechisch", + "da": "Deens", + "de": "Duits", + "el": "Grieks", + "en": "Engels", + "es": "Spaans", + "et-EE": "Ests", + "eu": "Baskisch", + "fa-IR": "Perzisch", + "fi": "Fins", + "fr": "Frans", + "ga-IE": "Iers", + "gl-ES": "Galicisch", + "gu-IN": "Gujarati", + "he": "Hebreeuws", + "hi-IN": "Hindi", + "hr-HR": "Kroatisch", + "hu": "Hongaars", + "id": "Indonesisch", + "it": "Italiaans", + "ja": "Japans", + "ka-GE": "Georgisch", + "kk-KZ": "Kazachs", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Koreaans", + "ky-KG": "Kirgizisch", + "lt-LT": "Litouws", + "lv-LV": "Lets", + "mk-MK": "Macedonisch", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Maleis", + "my": "Birmaans", + "nb": "BokmĂ„l", + "nl": "Nederlands", + "pa-IN": "Punjabi", + "pl": "Pools", + "pt-BR": "Portugees (BraziliĂ«)", + "pt-PT": "Portugees (Portugal)", + "ro-RO": "Roemeens", + "ru": "Russisch", + "sk-SK": "Slowaaks", + "sl-SI": "Sloveens", + "sq-AL": "Albanees", + "sr": "Servisch", + "sv": "Zweeds", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "Filipijns", + "tr": "Turks", + "ug": "Oeigoers", + "uk-UA": "OekraĂŻens", + "ur": "Urdu", + "vi": "Vietnamees", + "yue": "Kantonees", + "zh-CN": "Chinees (China)", + "zh-HK": "Chinees (Hongkong)", + "zh-Hant": "Chinees (traditioneel)" + }, + "pa-IN": { + "af-ZA": "àš…à©žàš°à©€àš•àšš", + "ar": "àš…àš°àšŹà©€", + "az-AZ": "àš…àšœàšŒàš°àšŹàšŸàšˆàšœàšŸàššà©€", + "bg-BG": "àšŹà©àšČàš—àšŸàš°à©€àš…àšš", + "bn-BD": "àšŹà©°àš—àšČàšŸ", + "bs-BA": "àšŹà©‹àšžàššà©€àš†", + "ca": "àš•à©ˆàšŸàšŸàšČàšŸàšš", + "cs": "àššà©ˆà©±àš•", + "da": "àšĄà©ˆàššàšżàš¶", + "de": "àšœàš°àšźàšš", + "el": "àš—à©àš°à©€àš•", + "en": "àš…à©°àš—àš°à©‡à©›à©€", + "es": "àšžàšȘà©ˆàššàšżàš¶", + "et-EE": "àšàšžàšŸà©‹àššà©€àš…àšš", + "eu": "àšŹàšŸàšžàš•", + "fa-IR": "à©žàšŸàš°àšžà©€", + "fi": "àš«àšżàššàšżàšžàšŒ", + "fr": "àš«àš°à©ˆàš‚àšš", + "ga-IE": "àš†àšˆàš°àšżàš¶", + "gl-ES": "àš—à©ˆàšČàšżàš•", + "gu-IN": "àš—à©àšœàš°àšŸàš€à©€", + "he": "àščàšżàšŹàš°à©‚", + "hi-IN": "àščàšżà©°àšŠà©€", + "hr-HR": "àš•à©àš°à©‹àšàšžàšŒà©€àš…àšš", + "hu": "àščà©°àš—à©‡àš°à©€àš…àšš", + "id": "àš‡à©°àšĄà©‹àššà©‡àšžàšŒà©€àš…àšš", + "it": "àš‡àšŸàšŸàšČà©€àš…àšš", + "ja": "àšœàšŸàšȘàšŸàššà©€", + "ka-GE": "àšœàšŸàš°àšœà©€àš…àšš", + "kk-KZ": "àš•àšœàšŒàšŸàš–", + "km-KH": "àš–àšźà©‡àš°", + "kn-IN": "àš•à©°àššà©œ", + "ko": "àš•à©‹àš°à©€àš…àšš", + "ky-KG": "àš•àšżàš°àš—àšżàšœàšŒ", + "lt-LT": "àšČàšżàš„à©àš†àššà©€àš…àšš", + "lv-LV": "àšČàšŸàš€àš”à©€àš…àšš", + "mk-MK": "àšźà©ˆàšžà©‡àšĄà©‹àššà©€àš…àšš", + "ml-IN": "àšźàšČàšżàš†àšČàšź", + "mr-IN": "àšźàš°àšŸàš à©€", + "ms": "àšźàšČੇ", + "my": "àšŹàš°àšźà©€àšœàšŒ", + "nb": "àššàšŸàš°àš”à©‡àšœàšżàš…àšš àšŹà©‹àš•àšźàšŸàšČ", + "nl": "àšĄà©±àšš", + "pa-IN": "àšȘà©°àšœàšŸàšŹà©€", + "pl": "àšȘੋàšČàšżàš¶", + "pt-BR": "àšŹà©àš°àšŸàšœàšŒà©€àšČà©€àš…àšš", + "pt-PT": "àšȘà©àš°àš€àš—àšŸàšČੀ", + "ro-RO": "àš°à©‹àšźàšŸàššà©€àš…àšš", + "ru": "àš°à©‚àšžà©€", + "sk-SK": "àšžàšČà©‹àš”àšŸàš•", + "sl-SI": "àšžàšČà©‹àš”à©‡àššà©€àš…àšš", + "sq-AL": "àš…àšČàšŹàšŸàššà©€àš…àšš", + "sr": "àšžàš°àšŹà©€àš…àšš", + "sv": "àšžàš”à©€àšĄàšżàšžàšŒ", + "sw": "àšžàš”àšŸàščàšżàšČੀ", + "ta-IN": "àš€àšŸàšźàšżàšČ", + "te-IN": "àš€à©‡àšČàš—à©‚", + "th": "àš„àšŸàšˆ", + "tl-PH": "àš«àšżàšČੀàšȘà©€àššà©‹", + "tr": "àš€à©àš°àš•à©€", + "ug": "àš‰àš‡àš˜à©àš°", + "uk-UA": "àšŻà©‚àš•àš°à©‡àššà©€", + "ur": "àš‰àš°àšŠà©‚", + "vi": "àš”à©€àš…àš€àššàšŸàšźà©€", + "yue": "àš•à©ˆàš‚àšŸà©‹àššà©€àšœàšŒ", + "zh-CN": "àššà©€àššà©€ (àššà©€àšš)", + "zh-HK": "àššà©€àššà©€ (àščàšŸàš‚àš—àš•àšŸàš‚àš—)", + "zh-Hant": "àš°àš”àšŸàš‡àš€à©€ àššà©€àššà©€" + }, + "pl": { + "af-ZA": "afrikaans", + "ar": "arabski", + "az-AZ": "azerbejdĆŒaƄski", + "bg-BG": "buƂgarski", + "bn-BD": "bengalski", + "bs-BA": "boƛniacki", + "ca": "kataloƄski", + "cs": "czeski", + "da": "duƄski", + "de": "niemiecki", + "el": "grecki", + "en": "angielski", + "es": "hiszpaƄski", + "et-EE": "estoƄski", + "eu": "baskijski", + "fa-IR": "perski", + "fi": "fiƄski", + "fr": "francuski", + "ga-IE": "irlandzki", + "gl-ES": "galicyjski", + "gu-IN": "gudĆŒarati", + "he": "hebrajski", + "hi-IN": "hindi", + "hr-HR": "chorwacki", + "hu": "węgierski", + "id": "indonezyjski", + "it": "wƂoski", + "ja": "japoƄski", + "ka-GE": "gruziƄski", + "kk-KZ": "kazachski", + "km-KH": "khmerski", + "kn-IN": "kannada", + "ko": "koreaƄski", + "ky-KG": "kirgiski", + "lt-LT": "litewski", + "lv-LV": "Ƃotewski", + "mk-MK": "macedoƄski", + "ml-IN": "malajalam", + "mr-IN": "marathi", + "ms": "malajski", + "my": "birmaƄski", + "nb": "norweski", + "nl": "niderlandzki", + "pa-IN": "pendĆŒabski", + "pl": "polski", + "pt-BR": "portugalski (Brazylia)", + "pt-PT": "portugalski (Portugalia)", + "ro-RO": "rumuƄski", + "ru": "rosyjski", + "sk-SK": "sƂowacki", + "sl-SI": "sƂoweƄski", + "sq-AL": "albaƄski", + "sr": "serbski", + "sv": "szwedzki", + "sw": "suahili", + "ta-IN": "tamilski", + "te-IN": "telugu", + "th": "tajski", + "tl-PH": "filipiƄski", + "tr": "turecki", + "ug": "ujgurski", + "uk-UA": "ukraiƄski", + "ur": "urdu", + "vi": "wietnamski", + "yue": "kantoƄski", + "zh-CN": "chiƄski (Chiny)", + "zh-HK": "chiƄski (Hongkong)", + "zh-Hant": "chiƄski tradycyjny" + }, + "pt-BR": { + "af-ZA": "africĂąner", + "ar": "ĂĄrabe", + "az-AZ": "azerbaijano", + "bg-BG": "bĂșlgaro", + "bn-BD": "bengali", + "bs-BA": "bĂłsnio", + "ca": "catalĂŁo", + "cs": "tcheco", + "da": "dinamarquĂȘs", + "de": "alemĂŁo", + "el": "grego", + "en": "inglĂȘs", + "es": "espanhol", + "et-EE": "estoniano", + "eu": "basco", + "fa-IR": "persa", + "fi": "finlandĂȘs", + "fr": "francĂȘs", + "ga-IE": "irlandĂȘs", + "gl-ES": "galego", + "gu-IN": "guzerate", + "he": "hebraico", + "hi-IN": "hĂ­ndi", + "hr-HR": "croata", + "hu": "hĂșngaro", + "id": "indonĂ©sio", + "it": "italiano", + "ja": "japonĂȘs", + "ka-GE": "georgiano", + "kk-KZ": "cazaque", + "km-KH": "khmer", + "kn-IN": "canarim", + "ko": "coreano", + "ky-KG": "quirguiz", + "lt-LT": "lituano", + "lv-LV": "letĂŁo", + "mk-MK": "macedĂŽnio", + "ml-IN": "malaiala", + "mr-IN": "marati", + "ms": "malaio", + "my": "birmanĂȘs", + "nb": "bokmĂ„l norueguĂȘs", + "nl": "holandĂȘs", + "pa-IN": "panjabi", + "pl": "polonĂȘs", + "pt-BR": "portuguĂȘs (Brasil)", + "pt-PT": "portuguĂȘs (Portugal)", + "ro-RO": "romeno", + "ru": "russo", + "sk-SK": "eslovaco", + "sl-SI": "esloveno", + "sq-AL": "albanĂȘs", + "sr": "sĂ©rvio", + "sv": "sueco", + "sw": "suaĂ­li", + "ta-IN": "tĂąmil", + "te-IN": "tĂ©lugo", + "th": "tailandĂȘs", + "tl-PH": "filipino", + "tr": "turco", + "ug": "uigur", + "uk-UA": "ucraniano", + "ur": "urdu", + "vi": "vietnamita", + "yue": "cantonĂȘs", + "zh-CN": "chinĂȘs (China)", + "zh-HK": "chinĂȘs (Hong Kong)", + "zh-Hant": "chinĂȘs tradicional" + }, + "pt-PT": { + "af-ZA": "africanĂȘs", + "ar": "ĂĄrabe", + "az-AZ": "azerbaijano", + "bg-BG": "bĂșlgaro", + "bn-BD": "bengalĂȘs", + "bs-BA": "bĂłsnio", + "ca": "catalĂŁo", + "cs": "checo", + "da": "dinamarquĂȘs", + "de": "alemĂŁo", + "el": "grego", + "en": "inglĂȘs", + "es": "espanhol", + "et-EE": "estĂłnio", + "eu": "basco", + "fa-IR": "persa", + "fi": "finlandĂȘs", + "fr": "francĂȘs", + "ga-IE": "irlandĂȘs", + "gl-ES": "galego", + "gu-IN": "guzerate", + "he": "hebraico", + "hi-IN": "hindi", + "hr-HR": "croata", + "hu": "hĂșngaro", + "id": "indonĂ©sio", + "it": "italiano", + "ja": "japonĂȘs", + "ka-GE": "georgiano", + "kk-KZ": "cazaque", + "km-KH": "khmer", + "kn-IN": "canarim", + "ko": "coreano", + "ky-KG": "quirguiz", + "lt-LT": "lituano", + "lv-LV": "letĂŁo", + "mk-MK": "macedĂłnio", + "ml-IN": "malaiala", + "mr-IN": "marata", + "ms": "malaio", + "my": "birmanĂȘs", + "nb": "norueguĂȘs bokmĂ„l", + "nl": "neerlandĂȘs", + "pa-IN": "panjabi", + "pl": "polaco", + "pt-BR": "portuguĂȘs do Brasil", + "pt-PT": "portuguĂȘs europeu", + "ro-RO": "romeno", + "ru": "russo", + "sk-SK": "eslovaco", + "sl-SI": "esloveno", + "sq-AL": "albanĂȘs", + "sr": "sĂ©rvio", + "sv": "sueco", + "sw": "suaĂ­li", + "ta-IN": "tĂąmil", + "te-IN": "telugu", + "th": "tailandĂȘs", + "tl-PH": "filipino", + "tr": "turco", + "ug": "uigur", + "uk-UA": "ucraniano", + "ur": "urdu", + "vi": "vietnamita", + "yue": "cantonĂȘs", + "zh-CN": "chinĂȘs (China)", + "zh-HK": "chinĂȘs (Hong Kong)", + "zh-Hant": "chinĂȘs tradicional" + }, + "ro-RO": { + "af-ZA": "afrikaans", + "ar": "arabă", + "az-AZ": "azeră", + "bg-BG": "bulgară", + "bn-BD": "bengaleză", + "bs-BA": "bosniacă", + "ca": "catalană", + "cs": "cehă", + "da": "daneză", + "de": "germană", + "el": "greacă", + "en": "engleză", + "es": "spaniolă", + "et-EE": "estonă", + "eu": "bască", + "fa-IR": "persană", + "fi": "finlandeză", + "fr": "franceză", + "ga-IE": "irlandeză", + "gl-ES": "galiciană", + "gu-IN": "gujarati", + "he": "ebraică", + "hi-IN": "hindi", + "hr-HR": "croată", + "hu": "maghiară", + "id": "indoneziană", + "it": "italiană", + "ja": "japoneză", + "ka-GE": "georgiană", + "kk-KZ": "kazahă", + "km-KH": "khmeră", + "kn-IN": "kannada", + "ko": "coreeană", + "ky-KG": "kĂąrgĂąză", + "lt-LT": "lituaniană", + "lv-LV": "letonă", + "mk-MK": "macedoneană", + "ml-IN": "malayalam", + "mr-IN": "marathi", + "ms": "malaeză", + "my": "birmană", + "nb": "norvegiană bokmĂ„l", + "nl": "neerlandeză", + "pa-IN": "punjabi", + "pl": "poloneză", + "pt-BR": "portugheză (Brazilia)", + "pt-PT": "portugheză (Europa)", + "ro-RO": "romĂąnă", + "ru": "rusă", + "sk-SK": "slovacă", + "sl-SI": "slovenă", + "sq-AL": "albaneză", + "sr": "sĂąrbă", + "sv": "suedeză", + "sw": "swahili", + "ta-IN": "tamilă", + "te-IN": "telugu", + "th": "thailandeză", + "tl-PH": "filipineză", + "tr": "turcă", + "ug": "uigură", + "uk-UA": "ucraineană", + "ur": "urdu", + "vi": "vietnameză", + "yue": "cantoneză", + "zh-CN": "chineză (China)", + "zh-HK": "chineză (Hong Kong)", + "zh-Hant": "chineză tradițională" + }, + "ru": { + "af-ZA": "АфроĐșĐ°Đ°ĐœŃ", + "ar": "АрабсĐșĐžĐč", + "az-AZ": "АзДрбаĐčĐŽĐ¶Đ°ĐœŃĐșĐžĐč", + "bg-BG": "Đ‘ĐŸĐ»ĐłĐ°Ń€ŃĐșĐžĐč", + "bn-BD": "Đ‘Đ”ĐœĐłĐ°Đ»ŃŒŃĐșĐžĐč", + "bs-BA": "Đ‘ĐŸŃĐœĐžĐčсĐșĐžĐč", + "ca": "ĐšĐ°Ń‚Đ°Đ»Đ°ĐœŃĐșĐžĐč", + "cs": "ЧДшсĐșĐžĐč", + "da": "ДатсĐșĐžĐč", + "de": "ĐĐ”ĐŒĐ”Ń†ĐșĐžĐč", + "el": "ГрДчДсĐșĐžĐč", + "en": "ĐĐœĐłĐ»ĐžĐčсĐșĐžĐč", + "es": "Đ˜ŃĐżĐ°ĐœŃĐșĐžĐč", + "et-EE": "Đ­ŃŃ‚ĐŸĐœŃĐșĐžĐč", + "eu": "БасĐșсĐșĐžĐč", + "fa-IR": "ĐŸĐ”Ń€ŃĐžĐŽŃĐșĐžĐč", + "fi": "Đ€ĐžĐœŃĐșĐžĐč", + "fr": "Đ€Ń€Đ°ĐœŃ†ŃƒĐ·ŃĐșĐžĐč", + "ga-IE": "Đ˜Ń€Đ»Đ°ĐœĐŽŃĐșĐžĐč", + "gl-ES": "ГалОсОĐčсĐșĐžĐč", + "gu-IN": "Đ“ŃƒĐŽĐ¶Đ°Ń€Đ°Ń‚Đž", + "he": "ИĐČрот", + "hi-IN": "Đ„ĐžĐœĐŽĐž", + "hr-HR": "Đ„ĐŸŃ€ĐČатсĐșĐžĐč", + "hu": "Đ’Đ”ĐœĐłĐ”Ń€ŃĐșĐžĐč", + "id": "Đ˜ĐœĐŽĐŸĐœĐ”Đ·ĐžĐčсĐșĐžĐč", + "it": "Đ˜Ń‚Đ°Đ»ŃŒŃĐœŃĐșĐžĐč", + "ja": "ĐŻĐżĐŸĐœŃĐșĐžĐč", + "ka-GE": "Đ“Ń€ŃƒĐ·ĐžĐœŃĐșĐžĐč", + "kk-KZ": "КазахсĐșĐžĐč", + "km-KH": "ĐšŃ…ĐŒĐ”Ń€ŃĐșĐžĐč", + "kn-IN": "ĐšĐ°ĐœĐœĐ°ĐŽĐ°", + "ko": "ĐšĐŸŃ€Đ”ĐčсĐșĐžĐč", + "ky-KG": "КОргОзсĐșĐžĐč", + "lt-LT": "Đ›ĐžŃ‚ĐŸĐČсĐșĐžĐč", + "lv-LV": "ЛатышсĐșĐžĐč", + "mk-MK": "МаĐșĐ”ĐŽĐŸĐœŃĐșĐžĐč", + "ml-IN": "ĐœĐ°Đ»Đ°ŃĐ»Đ°ĐŒ", + "mr-IN": "Маратхо", + "ms": "ĐœĐ°Đ»Đ°ĐčсĐșĐžĐč", + "my": "Đ‘ĐžŃ€ĐŒĐ°ĐœŃĐșĐžĐč", + "nb": "ĐĐŸŃ€ĐČДжсĐșĐžĐč буĐșĐŒĐŸĐ»", + "nl": "ĐĐžĐŽĐ”Ń€Đ»Đ°ĐœĐŽŃĐșĐžĐč", + "pa-IN": "ĐŸĐ°ĐœĐŽĐ¶Đ°Đ±Đž", + "pl": "ĐŸĐŸĐ»ŃŒŃĐșĐžĐč", + "pt-BR": "Đ‘Ń€Đ°Đ·ĐžĐ»ŃŒŃĐșĐžĐč ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃŒŃĐșĐžĐč", + "pt-PT": "ЕĐČŃ€ĐŸĐżĐ”ĐčсĐșĐžĐč ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃŒŃĐșĐžĐč", + "ro-RO": "Đ ŃƒĐŒŃ‹ĐœŃĐșĐžĐč", + "ru": "РуссĐșĐžĐč", + "sk-SK": "ĐĄĐ»ĐŸĐČацĐșĐžĐč", + "sl-SI": "ĐĄĐ»ĐŸĐČĐ”ĐœŃĐșĐžĐč", + "sq-AL": "ĐĐ»Đ±Đ°ĐœŃĐșĐžĐč", + "sr": "ХДрбсĐșĐžĐč", + "sv": "ĐšĐČДЎсĐșĐžĐč", + "sw": "ĐĄŃƒĐ°Ń…ĐžĐ»Đž", + "ta-IN": "ĐąĐ°ĐŒĐžĐ»ŃŒŃĐșĐžĐč", + "te-IN": "йДлугу", + "th": "йаĐčсĐșĐžĐč", + "tl-PH": "Đ€ĐžĐ»ĐžĐżĐżĐžĐœŃĐșĐžĐč", + "tr": "ĐąŃƒŃ€Đ”Ń†ĐșĐžĐč", + "ug": "ĐŁĐčгурсĐșĐžĐč", + "uk-UA": "ĐŁĐșŃ€Đ°ĐžĐœŃĐșĐžĐč", + "ur": "УрЮу", + "vi": "Đ’ŃŒĐ”Ń‚ĐœĐ°ĐŒŃĐșĐžĐč", + "yue": "ĐšĐ°ĐœŃ‚ĐŸĐœŃĐșĐžĐč", + "zh-CN": "КотаĐčсĐșĐžĐč (КотаĐč)", + "zh-HK": "КотаĐčсĐșĐžĐč (Đ“ĐŸĐœĐșĐŸĐœĐł)", + "zh-Hant": "КотаĐčсĐșĐžĐč (Ń‚Ń€Đ°ĐŽĐžŃ†ĐžĐŸĐœĐœĐŸĐ” ĐżĐžŃŃŒĐŒĐŸ)" + }, + "sk-SK": { + "af-ZA": "AfrikĂĄnčina", + "ar": "Arabčina", + "az-AZ": "AzerbajdĆŸančina", + "bg-BG": "Bulharčina", + "bn-BD": "BengĂĄlčina", + "bs-BA": "Bosniačtina", + "ca": "KatalĂĄnčina", + "cs": "ČeĆĄtina", + "da": "DĂĄnčina", + "de": "Nemčina", + "el": "GrĂ©Ätina", + "en": "Angličtina", + "es": "Ć panielčina", + "et-EE": "EstĂłnčina", + "eu": "Baskičtina", + "fa-IR": "PerzĆĄtina", + "fi": "FĂ­nčina", + "fr": "FrancĂșzĆĄtina", + "ga-IE": "Írčina", + "gl-ES": "GalĂ­cijčina", + "gu-IN": "GudĆŸarĂĄtčina", + "he": "Hebrejčina", + "hi-IN": "Hindčina", + "hr-HR": "ChorvĂĄtčina", + "hu": "Maďarčina", + "id": "IndonĂ©zĆĄtina", + "it": "Taliančina", + "ja": "Japončina", + "ka-GE": "GruzĂ­nčina", + "kk-KZ": "KazaĆĄtina", + "km-KH": "KhmĂ©rčina", + "kn-IN": "Kannadčina", + "ko": "KĂłrejčina", + "ky-KG": "KirgizĆĄtina", + "lt-LT": "Litovčina", + "lv-LV": "LotyĆĄtina", + "mk-MK": "MacedĂłnčina", + "ml-IN": "MalajĂĄlamčina", + "mr-IN": "MarĂĄthčina", + "ms": "Malajčina", + "my": "Barmčina", + "nb": "NĂłrčina", + "nl": "Holandčina", + "pa-IN": "PandĆŸĂĄbčina", + "pl": "PoÄŸĆĄtina", + "pt-BR": "Portugalčina (brazĂ­lska)", + "pt-PT": "Portugalčina (eurĂłpska)", + "ro-RO": "Rumunčina", + "ru": "RuĆĄtina", + "sk-SK": "Slovenčina", + "sl-SI": "Slovinčina", + "sq-AL": "AlbĂĄnčina", + "sr": "Srbčina", + "sv": "Ć vĂ©dčina", + "sw": "Swahilčina", + "ta-IN": "Tamilčina", + "te-IN": "Telugčina", + "th": "Thajčina", + "tl-PH": "FilipĂ­nčina", + "tr": "Turečtina", + "ug": "Ujgurčina", + "uk-UA": "Ukrajinčina", + "ur": "Urdčina", + "vi": "Vietnamčina", + "yue": "Kantončina", + "zh-CN": "ČínĆĄtina (Čína)", + "zh-HK": "ČínĆĄtina (Hongkong)", + "zh-Hant": "ČínĆĄtina (tradičnĂĄ)" + }, + "sl-SI": { + "af-ZA": "Afrikanơčina", + "ar": "Arabơčina", + "az-AZ": "AzerbajdĆŸanơčina", + "bg-BG": "Bolgarơčina", + "bn-BD": "Bengalơčina", + "bs-BA": "Bosanơčina", + "ca": "Katalonơčina", + "cs": "Čeơčina", + "da": "Danơčina", + "de": "Nemơčina", + "el": "Grơčina", + "en": "Angleơčina", + "es": "Ć panơčina", + "et-EE": "Estonơčina", + "eu": "Baskovơčina", + "fa-IR": "Perzijơčina", + "fi": "Finơčina", + "fr": "Francoơčina", + "ga-IE": "Irơčina", + "gl-ES": "Galicijơčina", + "gu-IN": "GudĆŸaratơčina", + "he": "Hebrejơčina", + "hi-IN": "Hindijơčina", + "hr-HR": "Hrvaơčina", + "hu": "MadĆŸarơčina", + "id": "Indonezijơčina", + "it": "Italijanơčina", + "ja": "Japonơčina", + "ka-GE": "Gruzijơčina", + "kk-KZ": "Kazaơčina", + "km-KH": "Kmerơčina", + "kn-IN": "Kanareơčina", + "ko": "Korejơčina", + "ky-KG": "Kirgiơčina", + "lt-LT": "Litovơčina", + "lv-LV": "Latvijơčina", + "mk-MK": "Makedonơčina", + "ml-IN": "Malajalamơčina", + "mr-IN": "Maratơčina", + "ms": "Malajơčina", + "my": "Burmanơčina", + "nb": "KnjiĆŸna norveơčina", + "nl": "Nizozemơčina", + "pa-IN": "PandĆŸabơčina", + "pl": "Poljơčina", + "pt-BR": "Brazilska portugalơčina", + "pt-PT": "Evropska portugalơčina", + "ro-RO": "Romunơčina", + "ru": "Ruơčina", + "sk-SK": "Slovaơčina", + "sl-SI": "Slovenơčina", + "sq-AL": "Albanơčina", + "sr": "Srbơčina", + "sv": "Ć vedơčina", + "sw": "Svahili", + "ta-IN": "Tamilơčina", + "te-IN": "Telugijơčina", + "th": "Tajơčina", + "tl-PH": "Filipinơčina", + "tr": "Turơčina", + "ug": "Ujgurơčina", + "uk-UA": "Ukrajinơčina", + "ur": "Urdujơčina", + "vi": "Vietnamơčina", + "yue": "Kantonơčina", + "zh-CN": "Kitajơčina (Kitajska)", + "zh-HK": "Kitajơčina (Hongkong)", + "zh-Hant": "Tradicionalna kitajơčina" + }, + "sq-AL": { + "af-ZA": "Afrikançe", + "ar": "Arabisht", + "az-AZ": "Azerbajxhanisht", + "bg-BG": "Bullgarisht", + "bn-BD": "Bengalisht", + "bs-BA": "Boshnjakisht", + "ca": "Katalanisht", + "cs": "Çekisht", + "da": "Danisht", + "de": "Gjermanisht", + "el": "Greqisht", + "en": "Anglisht", + "es": "Spanisht", + "et-EE": "Estonisht", + "eu": "Baskisht", + "fa-IR": "Persisht", + "fi": "Finlandisht", + "fr": "Frengjisht", + "ga-IE": "Irlandisht", + "gl-ES": "Galicisht", + "gu-IN": "Guxharatisht", + "he": "Hebraisht", + "hi-IN": "Hindustanisht", + "hr-HR": "Kroatisht", + "hu": "Hungarisht", + "id": "Indonezisht", + "it": "Italisht", + "ja": "Japonisht", + "ka-GE": "Gjeorgjisht", + "kk-KZ": "Kazakisht", + "km-KH": "Kmerisht", + "kn-IN": "Kanadisht", + "ko": "Koreançe", + "ky-KG": "Kirgizisht", + "lt-LT": "Lituanisht", + "lv-LV": "Letonisht", + "mk-MK": "Maqedonisht", + "ml-IN": "Malajalamisht", + "mr-IN": "Maratisht", + "ms": "Malajzisht", + "my": "Birmanisht", + "nb": "Norvegjeze BokmĂ„l", + "nl": "Holandisht", + "pa-IN": "Panxhabe", + "pl": "Polonisht", + "pt-BR": "Portugalisht brazilian", + "pt-PT": "Portugalisht europian", + "ro-RO": "Rumanisht", + "ru": "Rusisht", + "sk-SK": "Sllovakisht", + "sl-SI": "Sllovenisht", + "sq-AL": "Shqip", + "sr": "Serbisht", + "sv": "Suedisht", + "sw": "Suahile", + "ta-IN": "Tamil", + "te-IN": "Telegu", + "th": "Tajlandisht", + "tl-PH": "Filipinisht", + "tr": "Turqisht", + "ug": "Ujgurisht", + "uk-UA": "Ukrainisht", + "ur": "Urdu", + "vi": "Vietnamisht", + "yue": "Kantonezisht", + "zh-CN": "Kinezçe (Kina)", + "zh-HK": "Kinezçe (Hong Kong)", + "zh-Hant": "Kinezçe tradicionale" + }, + "sr": { + "af-ZA": "АфроĐșĐ°ĐœŃ", + "ar": "АрапсĐșĐž", + "az-AZ": "ĐĐ·Đ”Ń€Đ±Đ”Ń˜ŃŸĐ°ĐœŃĐșĐž", + "bg-BG": "БугарсĐșĐž", + "bn-BD": "Đ‘Đ”ĐœĐłĐ°Đ»ŃĐșĐž", + "bs-BA": "Đ‘ĐŸŃĐ°ĐœŃĐșĐž", + "ca": "ĐšĐ°Ń‚Đ°Đ»ĐŸĐœŃĐșĐž", + "cs": "ЧДшĐșĐž", + "da": "Đ”Đ°ĐœŃĐșĐž", + "de": "ĐĐ”ĐŒĐ°Ń‡ĐșĐž", + "el": "ГрчĐșĐž", + "en": "Đ•ĐœĐłĐ»Đ”ŃĐșĐž", + "es": "ĐšĐżĐ°ĐœŃĐșĐž", + "et-EE": "Đ•ŃŃ‚ĐŸĐœŃĐșĐž", + "eu": "БасĐșОјсĐșĐž", + "fa-IR": "ĐŸĐ”Ń€ŃĐžŃ˜ŃĐșĐž", + "fi": "Đ€ĐžĐœŃĐșĐž", + "fr": "Đ€Ń€Đ°ĐœŃ†ŃƒŃĐșĐž", + "ga-IE": "ИрсĐșĐž", + "gl-ES": "Đ“Đ°Đ»ĐžŃ†ĐžŃ˜ŃĐșĐž", + "gu-IN": "Гуџарато", + "he": "Đ„Đ”Đ±Ń€Đ”Ń˜ŃĐșĐž", + "hi-IN": "Đ„ĐžĐœĐŽĐž", + "hr-HR": "ЄрĐČатсĐșĐž", + "hu": "МађарсĐșĐž", + "id": "Đ˜ĐœĐŽĐŸĐœĐ”Đ¶Đ°ĐœŃĐșĐž", + "it": "Đ˜Ń‚Đ°Đ»ĐžŃ˜Đ°ĐœŃĐșĐž", + "ja": "ĐˆĐ°ĐżĐ°ĐœŃĐșĐž", + "ka-GE": "Đ“Ń€ŃƒĐ·ĐžŃ˜ŃĐșĐž", + "kk-KZ": "ĐšĐ°Đ·Đ°ŃˆĐșĐž", + "km-KH": "ĐšĐŒĐ”Ń€ŃĐșĐž", + "kn-IN": "ĐšĐ°ĐœĐ°ĐŽĐ°", + "ko": "ĐšĐŸŃ€Đ”Ń˜ŃĐșĐž", + "ky-KG": "КоргосĐșĐž", + "lt-LT": "ЛотĐČĐ°ĐœŃĐșĐž", + "lv-LV": "Đ›Đ”Ń‚ĐŸĐœŃĐșĐž", + "mk-MK": "МаĐșĐ”ĐŽĐŸĐœŃĐșĐž", + "ml-IN": "ĐœĐ°Đ»Đ°Ń˜Đ°Đ»Đ°ĐŒ", + "mr-IN": "Марато", + "ms": "ĐœĐ°Đ»Đ°Ń˜ŃĐșĐž", + "my": "Đ‘ŃƒŃ€ĐŒĐ°ĐœŃĐșĐž", + "nb": "ĐĐŸŃ€ĐČДшĐșĐž буĐșĐŒĐŸĐ»", + "nl": "Đ„ĐŸĐ»Đ°ĐœĐŽŃĐșĐž", + "pa-IN": "ĐŸĐ”ĐœŃŸĐ°ĐżŃĐșĐž", + "pl": "ĐŸĐŸŃ™ŃĐșĐž", + "pt-BR": "ĐŸĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃĐșĐž (БразОл)", + "pt-PT": "ĐŸĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃĐșĐž (ĐŸĐŸŃ€Ń‚ŃƒĐłĐ°Đ»)", + "ro-RO": "Đ ŃƒĐŒŃƒĐœŃĐșĐž", + "ru": "РусĐșĐž", + "sk-SK": "ĐĄĐ»ĐŸĐČачĐșĐž", + "sl-SI": "ĐĄĐ»ĐŸĐČĐ”ĐœĐ°Ń‡ĐșĐž", + "sq-AL": "ĐĐ»Đ±Đ°ĐœŃĐșĐž", + "sr": "СрпсĐșĐž", + "sv": "ĐšĐČДЎсĐșĐž", + "sw": "ĐĄĐČахОлО", + "ta-IN": "ĐąĐ°ĐŒĐžĐ»ŃĐșĐž", + "te-IN": "йДлугу", + "th": "йајсĐșĐž", + "tl-PH": "Đ€ĐžĐ»ĐžĐżĐžĐœŃĐșĐž", + "tr": "бурсĐșĐž", + "ug": "УјгурсĐșĐž", + "uk-UA": "ĐŁĐșŃ€Đ°Ń˜ĐžĐœŃĐșĐž", + "ur": "УрЮу", + "vi": "Đ’ĐžŃ˜Đ”Ń‚ĐœĐ°ĐŒŃĐșĐž", + "yue": "ĐšĐ°ĐœŃ‚ĐŸĐœŃĐșĐž", + "zh-CN": "ĐšĐžĐœĐ”ŃĐșĐž (ĐšĐžĐœĐ°)", + "zh-HK": "ĐšĐžĐœĐ”ŃĐșĐž (Đ„ĐŸĐœĐł ĐšĐŸĐœĐł)", + "zh-Hant": "ĐąŃ€Đ°ĐŽĐžŃ†ĐžĐŸĐœĐ°Đ»ĐœĐž ĐșĐžĐœĐ”ŃĐșĐž" + }, + "sv": { + "af-ZA": "Afrikaans", + "ar": "Arabiska", + "az-AZ": "Azerbajdzjanska", + "bg-BG": "Bulgariska", + "bn-BD": "Bengali", + "bs-BA": "Bosniska", + "ca": "Katalanska", + "cs": "Tjeckiska", + "da": "Danska", + "de": "Tyska", + "el": "Grekiska", + "en": "Engelska", + "es": "Spanska", + "et-EE": "Estniska", + "eu": "Baskiska", + "fa-IR": "Persiska", + "fi": "Finska", + "fr": "Franska", + "ga-IE": "Iriska", + "gl-ES": "Galiciska", + "gu-IN": "Gujarati", + "he": "Hebreiska", + "hi-IN": "Hindi", + "hr-HR": "Kroatiska", + "hu": "Ungerska", + "id": "Indonesiska", + "it": "Italienska", + "ja": "Japanska", + "ka-GE": "Georgiska", + "kk-KZ": "Kazakiska", + "km-KH": "Kambodjanska", + "kn-IN": "Kannada", + "ko": "Koreanska", + "ky-KG": "Kirgiziska", + "lt-LT": "Litauiska", + "lv-LV": "Lettiska", + "mk-MK": "Makedonska", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Malajiska", + "my": "Burmesiska", + "nb": "Norskt bokmĂ„l", + "nl": "NederlĂ€ndska", + "pa-IN": "Punjabi", + "pl": "Polska", + "pt-BR": "Brasiliansk portugisiska", + "pt-PT": "Europeisk portugisiska", + "ro-RO": "RumĂ€nska", + "ru": "Ryska", + "sk-SK": "Slovakiska", + "sl-SI": "Slovenska", + "sq-AL": "Albanska", + "sr": "Serbiska", + "sv": "Svenska", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "ThailĂ€ndska", + "tl-PH": "Filippinska", + "tr": "Turkiska", + "ug": "Uiguriska", + "uk-UA": "Ukrainska", + "ur": "Urdu", + "vi": "Vietnamesiska", + "yue": "Kantonesiska", + "zh-CN": "Kinesiska (Kina)", + "zh-HK": "Kinesiska (Hongkong)", + "zh-Hant": "Traditionell kinesiska" + }, + "sw": { + "af-ZA": "Kiafrikana", + "ar": "Kiarabu", + "az-AZ": "Kiazerbaijani", + "bg-BG": "Kibulgaria", + "bn-BD": "Kibengali", + "bs-BA": "Kibosnia", + "ca": "Kikatalani", + "cs": "Kicheki", + "da": "Kidenmaki", + "de": "Kijerumani", + "el": "Kigiriki", + "en": "Kiingereza", + "es": "Kihispania", + "et-EE": "Kiestonia", + "eu": "Kibaski", + "fa-IR": "Kiajemi", + "fi": "Kifini", + "fr": "Kifaransa", + "ga-IE": "Kiayalandi", + "gl-ES": "Kigalisi", + "gu-IN": "Kigujarati", + "he": "Kiebrania", + "hi-IN": "Kihindi", + "hr-HR": "Kikroasia", + "hu": "Kihungaria", + "id": "Kiindonesia", + "it": "Kiitaliano", + "ja": "Kijapani", + "ka-GE": "Kijojia", + "kk-KZ": "Kikazakh", + "km-KH": "Kikambodia", + "kn-IN": "Kikannada", + "ko": "Kikorea", + "ky-KG": "Kikyrgyz", + "lt-LT": "Kilithuania", + "lv-LV": "Kilatvia", + "mk-MK": "Kimacedonia", + "ml-IN": "Kimalayalamu", + "mr-IN": "Kimarathi", + "ms": "Kimalei", + "my": "Kiburma", + "nb": "Kinorwe cha Bokmal", + "nl": "Kiholanzi", + "pa-IN": "Kipunjabi", + "pl": "Kipolandi", + "pt-BR": "Kireno (Brazili)", + "pt-PT": "Kireno (Ulaya)", + "ro-RO": "Kiromania", + "ru": "Kirusi", + "sk-SK": "Kislovakia", + "sl-SI": "Kislovenia", + "sq-AL": "Kialbania", + "sr": "Kiserbia", + "sv": "Kiswidi", + "sw": "Kiswahili", + "ta-IN": "Kitamili", + "te-IN": "Kitelugu", + "th": "Kithai", + "tl-PH": "Kifilipino", + "tr": "Kituruki", + "ug": "Kiuyghur", + "uk-UA": "Kiukraini", + "ur": "Kiurdu", + "vi": "Kivietinamu", + "yue": "Kikantoni", + "zh-CN": "Kichina (Uchina)", + "zh-HK": "Kichina (Hong Kong)", + "zh-Hant": "Kichina cha Jadi" + }, + "ta-IN": { + "af-ZA": "àź†àźƒàźȘàŻàź°àźżàź•àźŸàź©àŻàźžàŻ", + "ar": "àź…àź°àźȘàźżàź•àŻ", + "az-AZ": "àź…àźšàź°àŻàźȘàŻˆàźœàźŸàź©àźż", + "bg-BG": "àźȘàźČàŻàź•àŻ‡àź°àźżàźŻàź©àŻ", + "bn-BD": "àź”àź™àŻàź•àźŸàźłàźźàŻ", + "bs-BA": "àźȘàŻ‹àźžàŻàź©àźżàźŻàź©àŻ", + "ca": "àź•àŻ‡àźŸàŻàźŸàźČàźŸàź©àŻ", + "cs": "àźšàŻ†àź•àŻ", + "da": "àźŸàŻ‡àź©àźżàź·àŻ", + "de": "àźœàŻ†àź°àŻàźźàź©àŻ", + "el": "àź•àźżàź°àŻ‡àź•àŻàź•àźźàŻ", + "en": "àź†àź™àŻàź•àźżàźČàźźàŻ", + "es": "àźžàŻàźȘàźŸàź©àźżàź·àŻ", + "et-EE": "àźŽàźžàŻàźŸàŻ‹àź©àźżàźŻàź©àŻ", + "eu": "àźȘàźŸàźžàŻàź•àŻ", + "fa-IR": "àźȘàŻ†àź°àŻàź·àźżàźŻàź©àŻ", + "fi": "àźƒàźȘàźżàź©àŻàź©àźżàź·àŻ", + "fr": "àźȘàźżàź°àŻ†àźžàŻàźšàŻ", + "ga-IE": "àźàź°àźżàź·àŻ", + "gl-ES": "àź•àźŸàźČàźżàźžàźżàźŻàź©àŻ", + "gu-IN": "àź•àŻàźœàź°àźŸàź€àŻàź€àźż", + "he": "àźčàŻ€àźȘàŻàź°àŻ‚", + "hi-IN": "àź‡àźšàŻàź€àźż", + "hr-HR": "àź•àŻàź°àŻ‹àź·àźżàźŻàź©àŻ", + "hu": "àźčàź™àŻàź•àŻ‡àź°àźżàźŻàź©àŻ", + "id": "àź‡àźšàŻàź€àŻ‹àź©àŻ‡àź·àźżàźŻàź©àŻ", + "it": "àź‡àź€àŻàź€àźŸàźČàźżàźŻàź©àŻ", + "ja": "àźœàźȘàŻàźȘàźŸàź©àźżàźŻàźźàŻ", + "ka-GE": "àźœàźŸàź°àŻàźœàźżàźŻàź©àŻ", + "kk-KZ": "àź•àźšàźŸàź•àŻ", + "km-KH": "àź•àŻ†àźźàŻ†àź°àŻ", + "kn-IN": "àź•àź©àŻàź©àźŸàźźàŻ", + "ko": "àź•àŻŠàź°àźżàźŻàź©àŻ", + "ky-KG": "àź•àźżàź°àŻàź•àźżàźžàŻ", + "lt-LT": "àźČàźżàź€àŻàź”àŻ‡àź©àźżàźŻàź©àŻ", + "lv-LV": "àźČàźŸàźŸàŻàź”àźżàźŻàź©àŻ", + "mk-MK": "àźźàźŸàźžàźżàźŸàŻ‹àź©àźżàźŻàź©àŻ", + "ml-IN": "àźźàźČàŻˆàźŻàźŸàźłàźźàŻ", + "mr-IN": "àźźàź°àźŸàź€àŻàź€àźż", + "ms": "àźźàźČàźŸàźŻàŻ", + "my": "àźȘàź°àŻàźźàŻ€àźžàŻ", + "nb": "àźšàźŸàź°àŻàź”àŻ‡àźœàźżàźŻàź©àŻ àźȘàŻŠàź•àŻàźźàźŸàźČàŻ", + "nl": "àźŸàźšàŻàźšàŻ", + "pa-IN": "àźȘàźžàŻàźšàźŸàźȘàźż", + "pl": "àźȘàŻ‹àźČàźżàź·àŻ", + "pt-BR": "àźȘàźżàź°àŻ‡àźšàźżàźČàźżàźŻ àźȘàŻ‹àź°àŻàźšàŻàźšàŻàź•àŻ€àźžàŻ", + "pt-PT": "àźàź°àŻ‹àźȘàŻàźȘàźżàźŻ àźȘàŻ‹àź°àŻàźšàŻàźšàŻàź•àŻ€àźžàŻ", + "ro-RO": "àź°àŻ‹àźźàŻ‡àź©àźżàźŻàź©àŻ", + "ru": "àź°àź·àźżàźŻàź©àŻ", + "sk-SK": "àźžàŻàźČàŻ‹àź”àźŸàź•àŻ", + "sl-SI": "àźžàŻàźČàŻ‹àź”àŻ‡àź©àźżàźŻàź©àŻ", + "sq-AL": "àź…àźČàŻàźȘàŻ‡àź©àźżàźŻàź©àŻ", + "sr": "àźšàŻ†àź°àŻàźȘàźżàźŻàź©àŻ", + "sv": "àźžàŻàź”àŻ€àźŸàźżàź·àŻ", + "sw": "àźžàŻàź”àźŸàźčàźżàźČàźż", + "ta-IN": "àź€àźźàźżàźŽàŻ", + "te-IN": "àź€àŻ†àźČàŻàź™àŻàź•àŻ", + "th": "àź€àźŸàźŻàŻ", + "tl-PH": "àźƒàźȘàźżàźČàźżàźȘàźżàź©àŻ‹", + "tr": "àź€àŻàź°àŻàź•àŻàź•àźżàź·àŻ", + "ug": "àź‰àźŻàŻàź•àŻàź°àŻ", + "uk-UA": "àź‰àź•àŻàź°àŻˆàź©àźżàźŻàź©àŻ", + "ur": "àź‰àź°àŻàź€àŻ", + "vi": "àź”àźżàźŻàźŸàŻàźšàźŸàźźàŻ€àźžàŻ", + "yue": "àź•àźŸàźŁàŻàźŸàŻ‹àź©àŻ€àźžàŻ", + "zh-CN": "àźšàŻ€àź©àźźàŻ (àźšàŻ€àź©àźŸ)", + "zh-HK": "àźšàŻ€àź©àźźàŻ (àźčàźŸàź™àŻàź•àźŸàź™àŻ)", + "zh-Hant": "àźȘàźŸàź°àźźàŻàźȘàź°àźżàźŻ àźšàŻ€àź©àźźàŻ" + }, + "te-IN": { + "af-ZA": "à°†à°«à±à°°à°żà°•à°Ÿà°šà±à°žà±", + "ar": "à°…à°°à°Źà°żà°•à±", + "az-AZ": "à°…à°œà°°à±à°Źà±ˆà°œà°Ÿà°šà°ż", + "bg-BG": "à°Źà°Čà±à°—à±‡à°°à°żà°Żà°šà±", + "bn-BD": "à°Źà°‚à°—à±à°Čà°Ÿ", + "bs-BA": "à°Źà±‹à°žà±à°šà°żà°Żà°šà±", + "ca": "à°•à°Ÿà°Ÿà°Čటచ్", + "cs": "చెక్", + "da": "à°Ąà°Ÿà°šà°żà°·à±", + "de": "à°œà°°à±à°źà°šà±", + "el": "గ్రీక్", + "en": "ఇంగ్à°Čీష్", + "es": "ఞ్à°Șà°Ÿà°šà°żà°·à±", + "et-EE": "à°Žà°žà±à°Ÿà±‹à°šà°żà°Żà°šà±", + "eu": "à°Źà°Ÿà°žà±à°•à±à°Żà±‚", + "fa-IR": "à°Șà°°à±à°·à°żà°Żà°šà±", + "fi": "à°«à°żà°šà±à°šà°żà°·à±", + "fr": "ఫ్రెంచ్", + "ga-IE": "à°à°°à°żà°·à±", + "gl-ES": "à°—à°Ÿà°Čà°żà°·à°żà°Żà°šà±", + "gu-IN": "à°—à±à°œà°°à°Ÿà°€à°ż", + "he": "à°čà°żà°Źà±à°°à±‚", + "hi-IN": "à°čà°żà°‚à°Šà±€", + "hr-HR": "à°•à±à°°à±Šà°Żà±‡à°·à°żà°Żà°šà±", + "hu": "à°čà°‚à°—à±‡à°°à°żà°Żà°šà±", + "id": "à°‡à°‚à°Ąà±‹à°šà±‡à°·à°żà°Żà°šà±", + "it": "ఇటటà°Čà°żà°Żà°šà±", + "ja": "జà°Șచీఞ్", + "ka-GE": "à°œà°Ÿà°°à±à°œà°żà°Żà°šà±", + "kk-KZ": "కజఖ్", + "km-KH": "à°–à±à°źà±‡à°°à±", + "kn-IN": "à°•à°šà±à°šà°Ą", + "ko": "à°•à±Šà°°à°żà°Żà°šà±", + "ky-KG": "à°•à°żà°°à±à°—à°żà°œà±", + "lt-LT": "à°Čà°żà°„à±à°”à±‡à°šà°żà°Żà°šà±", + "lv-LV": "à°Čà°Ÿà°Ÿà±à°”à°żà°Żà°šà±", + "mk-MK": "à°źà°Ÿà°žà°żà°Ąà±‹à°šà°żà°Żà°šà±", + "ml-IN": "à°źà°Čà°Żà°Ÿà°łà°‚", + "mr-IN": "à°źà°°à°Ÿà° à±€", + "ms": "à°źà°Čà°Żà±", + "my": "à°Źà°°à±à°źà±€à°žà±", + "nb": "à°šà°Ÿà°°à±à°”à±‡à°œà°żà°Żà°šà± à°Źà±Šà°•à±à°źà°Ÿà°Č్", + "nl": "à°Ąà°šà±", + "pa-IN": "à°Șà°‚à°œà°Ÿà°Źà±€", + "pl": "à°Șోà°Čà°żà°·à±", + "pt-BR": "à°Źà±à°°à±†à°œà±€à°Čà°żà°Żà°šà± à°Șోర్చుగీఞ్", + "pt-PT": "à°Żà±‚à°°à±‹à°Șà°żà°Żà°šà± à°Șోర్చుగీఞ్", + "ro-RO": "à°°à±‹à°źà±‡à°šà°żà°Żà°šà±", + "ru": "à°°à°·à±à°Żà°šà±", + "sk-SK": "ఞ్à°Čోఔక్", + "sl-SI": "ఞ్à°Čà±‹à°”à±‡à°šà°żà°Żà°šà±", + "sq-AL": "అà°Čà±à°Źà±‡à°šà°żà°Żà°šà±", + "sr": "à°žà±†à°°à±à°Źà°żà°Żà°šà±", + "sv": "à°žà±à°”à±€à°Ąà°żà°·à±", + "sw": "ఞ్ఔటà°čà°żà°Čà°ż", + "ta-IN": "à°€à°źà°żà°łà°źà±", + "te-IN": "ఀెà°Čుగు", + "th": "à°„à°Ÿà°Żà±", + "tl-PH": "à°«à°żà°Čà°żà°Șà°żà°šà±‹", + "tr": "à°Ÿà°°à±à°•à°żà°·à±", + "ug": "à°‰à°Żà±â€Œà°˜à°°à±", + "uk-UA": "à°‰à°•à±à°°à±†à°Żà°żà°šà°żà°Żà°šà±", + "ur": "ఉర్ఊూ", + "vi": "à°”à°żà°Żà°€à±à°šà°Ÿà°źà±€à°žà±", + "yue": "కటంటచీఞ్", + "zh-CN": "చైచీఞ్ (చైచట)", + "zh-HK": "చైచీఞ్ (à°čటంకటంగ్)", + "zh-Hant": "à°žà°Ÿà°‚à°Șà±à°°à°Šà°Ÿà°Żà°• చైచీఞ్" + }, + "th": { + "af-ZA": "àčàž­àžŸàžŁàžŽàžàžČàž™àžȘàčŒ", + "ar": "àž­àžČàž«àžŁàž±àžš", + "az-AZ": "àž­àžČàč€àž‹àž­àžŁàčŒàč„àžšàžˆàžČàž™", + "bg-BG": "àžšàž±àž„àčàžàč€àžŁàž”àžą", + "bn-BD": "àč€àžšàž‡àžàžČàž„àž”", + "bs-BA": "àžšàž­àžȘàč€àž™àž”àžą", + "ca": "àž„àžČàž•àžČàž„àž±àž™", + "cs": "àč€àžŠàč‡àž", + "da": "àč€àž”àž™àžĄàžČàžŁàčŒàž", + "de": "àč€àžąàž­àžŁàžĄàž±àž™", + "el": "àžàžŁàž”àž", + "en": "àž­àž±àž‡àžàž€àž©", + "es": "àžȘàč€àž›àž™", + "et-EE": "àč€àž­àžȘàč‚àž•àč€àž™àž”àžą", + "eu": "àžšàžČàžȘàžàčŒ", + "fa-IR": "àč€àž›àž­àžŁàčŒàč€àž‹àž”àžą", + "fi": "àžŸàžŽàž™àčàž„àž™àž”àčŒ", + "fr": "àžàžŁàž±àčˆàž‡àč€àžšàžȘ", + "ga-IE": "àč„àž­àžŁàžŽàžŠ", + "gl-ES": "àžàžČàž„àžŽàč€àž‹àž”àžą", + "gu-IN": "àž„àžžàžŠàžŁàžČàž•", + "he": "àžźàž”àžšàžŁàžč", + "hi-IN": "àžźàžŽàž™àž”àž”", + "hr-HR": "àč‚àž„àžŁàč€àž­àč€àžŠàž”àžą", + "hu": "àžźàž±àž‡àžàžČàžŁàž”", + "id": "àž­àžŽàž™àč‚àž”àž™àž”àč€àž‹àž”àžą", + "it": "àž­àžŽàž•àžČàž„àž”", + "ja": "àžàž”àčˆàž›àžžàčˆàž™", + "ka-GE": "àžˆàž­àžŁàčŒàč€àžˆàž”àžą", + "kk-KZ": "àž„àžČàž‹àž±àž„", + "km-KH": "àč€àž‚àžĄàžŁ", + "kn-IN": "àžàž±àž™àž™àžČàž”àžČ", + "ko": "àč€àžàžČàž«àž„àž”", + "ky-KG": "àž„àž”àžŁàčŒàžàž”àž‹", + "lt-LT": "àž„àžŽàž—àž±àž§àč€àž™àž”àžą", + "lv-LV": "àž„àž±àž•àč€àž§àž”àžą", + "mk-MK": "àžĄàžČàž‹àžŽàč‚àž”àč€àž™àž”àžą", + "ml-IN": "àžĄàžČàž„àžČàžąàžČàž„àž±àžĄ", + "mr-IN": "àžĄàžŁàžČàžàž”", + "ms": "àžĄàžČàč€àž„àžąàčŒ", + "my": "àžžàžĄàčˆàžČ", + "nb": "àž™àž­àžŁàčŒàč€àž§àžąàčŒàžšàžžàž„àžĄàž­àž„", + "nl": "àž”àž±àž•àžŠàčŒ", + "pa-IN": "àž›àž±àžàžˆàžČàžš", + "pl": "àč‚àž›àčàž„àž™àž”àčŒ", + "pt-BR": "àč‚àž›àžŁàž•àžžàč€àžàžȘ (àžšàžŁàžČàž‹àžŽàž„)", + "pt-PT": "àč‚àž›àžŁàž•àžžàč€àžàžȘ (àžąàžžàč‚àžŁàž›)", + "ro-RO": "àč‚àžŁàžĄàžČàč€àž™àž”àžą", + "ru": "àžŁàž±àžȘàč€àž‹àž”àžą", + "sk-SK": "àžȘàč‚àž„àž§àž±àž", + "sl-SI": "àžȘàč‚àž„àž§àž”àč€àž™àž”àžą", + "sq-AL": "àčàž­àž„àč€àžšàč€àž™àž”àžą", + "sr": "àč€àž‹àž­àžŁàčŒàč€àžšàž”àžą", + "sv": "àžȘàž§àž”àč€àž”àž™", + "sw": "àžȘàž§àžČàžźàž”àž„àž”", + "ta-IN": "àž—àžĄàžŽàžŹ", + "te-IN": "àč€àž•àž„àžčàžàžč", + "th": "àč„àž—àžą", + "tl-PH": "àžŸàžŽàž„àžŽàž›àž›àžŽàž™àžȘàčŒ", + "tr": "àž•àžžàžŁàžàž”", + "ug": "àž­àžžàžąàžàžčàžŁàčŒ", + "uk-UA": "àžąàžčàč€àž„àžŁàž™", + "ur": "àž­àžčàžŁàž”àžč", + "vi": "àč€àž§àž”àžąàž”àž™àžČàžĄ", + "yue": "àžàž§àžČàž‡àž•àžžàč‰àž‡", + "zh-CN": "àžˆàž”àž™ (àžˆàž”àž™)", + "zh-HK": "àžˆàž”àž™ (àžźàčˆàž­àž‡àžàž‡)", + "zh-Hant": "àžˆàž”àž™àž•àž±àž§àč€àž•àč‡àžĄ" + }, + "tl-PH": { + "af-ZA": "Afrikaans", + "ar": "Arabic", + "az-AZ": "Azerbaijani", + "bg-BG": "Bulgarian", + "bn-BD": "Bangla", + "bs-BA": "Bosnian", + "ca": "Catalan", + "cs": "Czech", + "da": "Danish", + "de": "German", + "el": "Greek", + "en": "English", + "es": "Spanish", + "et-EE": "Estonian", + "eu": "Basque", + "fa-IR": "Persian", + "fi": "Finnish", + "fr": "French", + "ga-IE": "Irish", + "gl-ES": "Galician", + "gu-IN": "Gujarati", + "he": "Hebrew", + "hi-IN": "Hindi", + "hr-HR": "Croatian", + "hu": "Hungarian", + "id": "Indonesian", + "it": "Italian", + "ja": "Japanese", + "ka-GE": "Georgian", + "kk-KZ": "Kazakh", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Korean", + "ky-KG": "Kirghiz", + "lt-LT": "Lithuanian", + "lv-LV": "Latvian", + "mk-MK": "Macedonian", + "ml-IN": "Malayalam", + "mr-IN": "Marathi", + "ms": "Malay", + "my": "Burmese", + "nb": "Norwegian BokmĂ„l", + "nl": "Dutch", + "pa-IN": "Punjabi", + "pl": "Polish", + "pt-BR": "Portuguese (Brazil)", + "pt-PT": "Portuguese (Portugal)", + "ro-RO": "Romanian", + "ru": "Russian", + "sk-SK": "Slovak", + "sl-SI": "Slovenian", + "sq-AL": "Albanian", + "sr": "Serbian", + "sv": "Swedish", + "sw": "Swahili", + "ta-IN": "Tamil", + "te-IN": "Telugu", + "th": "Thai", + "tl-PH": "Filipino", + "tr": "Turkish", + "ug": "Uyghur", + "uk-UA": "Ukranian", + "ur": "Urdu", + "vi": "Vietnamese", + "yue": "Cantonese", + "zh-CN": "Chinese (China)", + "zh-HK": "Chinese (Hong Kong)", + "zh-Hant": "Traditional Chinese" + }, + "tr": { + "af-ZA": "Afrikanca", + "ar": "Arapça", + "az-AZ": "Azerice", + "bg-BG": "Bulgarca", + "bn-BD": "Bengalce", + "bs-BA": "Boßnakça", + "ca": "Katalanca", + "cs": "Çekçe", + "da": "Danca", + "de": "Almanca", + "el": "Yunanca", + "en": "İngilizce", + "es": "İspanyolca", + "et-EE": "Estonca", + "eu": "Baskça", + "fa-IR": "Farsça", + "fi": "Fince", + "fr": "Fransızca", + "ga-IE": "İrlandaca", + "gl-ES": "Galiçyaca", + "gu-IN": "GĂŒcaratça", + "he": "İbranice", + "hi-IN": "Hintçe", + "hr-HR": "Hırvatça", + "hu": "Macarca", + "id": "Endonezce", + "it": "İtalyanca", + "ja": "Japonca", + "ka-GE": "GĂŒrcĂŒce", + "kk-KZ": "Kazakça", + "km-KH": "Khmer", + "kn-IN": "Kannada", + "ko": "Korece", + "ky-KG": "Kırgızca", + "lt-LT": "Litvanca", + "lv-LV": "Letonca", + "mk-MK": "Makedonca", + "ml-IN": "Malayalam", + "mr-IN": "Marati", + "ms": "Malayca", + "my": "Birmanca", + "nb": "Norveççe BokmĂ„l", + "nl": "Felemenkçe", + "pa-IN": "Pencapça", + "pl": "Lehçe", + "pt-BR": "Brezilya Portekizcesi", + "pt-PT": "Avrupa Portekizcesi", + "ro-RO": "Romence", + "ru": "Rusça", + "sk-SK": "Slovakça", + "sl-SI": "Slovence", + "sq-AL": "Arnavutça", + "sr": "Sırpça", + "sv": "İsveççe", + "sw": "Svahili", + "ta-IN": "Tamilce", + "te-IN": "Telugu", + "th": "Tayca", + "tl-PH": "Filipince", + "tr": "TĂŒrkçe", + "ug": "Uygurca", + "uk-UA": "Ukraynaca", + "ur": "Urduca", + "vi": "Vietnamca", + "yue": "Kantonca", + "zh-CN": "Çince (Çin)", + "zh-HK": "Çince (Hong Kong)", + "zh-Hant": "Geleneksel Çince" + }, + "ug": { + "af-ZA": "ŰŠŰ§ÙŰ±Ù‰Ù‚Ù‰Ú†Û•", + "ar": "ŰŠÛ•Ű±Û•ŰšÚ†Û•", + "az-AZ": "ŰŠÛ•ŰČŰ§Ű±ŰšÛ•ÙŠŰŹŰ§Ù†Ú†Û•", + "bg-BG": "ŰšÛ‡Ù„ŰșŰ§Ű±Ú†Û•", + "bn-BD": "ŰšÛÙ†ÚŻŰ§Ù„Ù‰Ú†Û•", + "bs-BA": "ŰšÙˆŰłÙ†Ù‰ÙŠÛ•Ú†Û•", + "ca": "ÙƒŰ§ŰȘŰ§Ù„Ű§Ù†Ú†Û•", + "cs": "Ú†ÛÙ‰ŰźÚ†Û•", + "da": "ŰŻŰ§Ù†Ù‰ÙŠÛ•Ú†Û•", + "de": "ÚŻÛŰ±Ù…Ű§Ù†Ú†Û•", + "el": "ÚŻÛŰ±Ù‰ÙƒÚ†Û•", + "en": "ŰŠÛÙ†ÚŻÙ„Ù‰ŰČچە", + "es": "ŰŠÙ‰ŰłÙŸŰ§Ù†Ú†Û•", + "et-EE": "ŰŠÛŰłŰȘونچە", + "eu": "ŰšŰ§ŰŽÙ‚Û•Ú†Û•", + "fa-IR": "ÙŸŰ§Ű±ŰłÚ†Û•", + "fi": "فىنچە", + "fr": "ÙŰ±Ű§Ù†ŰłÛ‡ŰČچە", + "ga-IE": "ŰŠÛŰ±Ù„Ű§Ù†ŰŻÙ‰Ú†Û•", + "gl-ES": "ÚŻŰ§Ù„Ù‰ŰłÙ‰ÙŠÛ•Ù†Ú†Û•", + "gu-IN": "ÚŻÛ‡ŰŹŰ§Ű±ÛŰȘچە", + "he": "ŰŠÙ‰ŰšŰ±Ű§Ù†Ù‰Ú†Û•", + "hi-IN": "ÚŸÙ‰Ù†ŰŻÙ‰Ú†Û•", + "hr-HR": "ÙƒÙ‰Ű±ÙˆŰŻÙ‰ÙŠÛ•Ú†Û•", + "hu": "Û‹Ù‰Ù†ÚŻÙ‰Ű±Ú†Û•", + "id": "ÚŸÙ‰Ù†ŰŻÙ‰Ù†ÙˆŰČىيەچە", + "it": "ŰŠÙ‰ŰȘŰ§Ù„Ù‰ÙŠŰ§Ù†Ú†Û•", + "ja": "ÙŠŰ§ÙŸÙˆÙ†Ú†Û•", + "ka-GE": "ÚŻÙ‰Ű±Û‡ŰČىنچە", + "kk-KZ": "Ù‚Ű§ŰČŰ§Ù‚Ú†Û•", + "km-KH": "ÙƒÙ…ÛŰ±Ú†Û•", + "kn-IN": "ÙƒŰ§Ù†Ù†Ű§ŰŻŰ§Ú†Û•", + "ko": "ÙƒÙˆŰ±ÛÙŠŰ§Ù†Ú†Û• (ÙƒÙˆŰ±ÛÙŠÛ•)", + "ky-KG": "Ù‚Ù‰Ű±ŰșىŰČچە", + "lt-LT": "لىŰȘÛ‹Ű§Ú†Û•", + "lv-LV": "Ù„Ű§ŰȘۋىيەچە", + "mk-MK": "Ù…Ű§ÙƒÛŰŻÙˆÙ†Ù‰ÙŠÛ•Ú†Û•", + "ml-IN": "Ù…Ű§Ù„Ű§ÙŠŰ§Ù„Ű§Ù…Ú†Û•", + "mr-IN": "Ù…Ű§Ű±Ű§ŰȘىچە", + "ms": "Ù…Ű§Ù„Ű§ÙŠÚ†Û•", + "my": "ŰšÙ‰Ű±Ù…Ù‰Ú†Û•", + "nb": "Ù†ÙˆŰ±Û‹Ù‰ÚŻÙ‰ÙŠÛ• ŰšÙˆÙƒÙ…Ű§Ù„Ú†Û•", + "nl": "ÚŻÙˆÙ„Ù„Ű§Ù†ŰŻÙ‰ÙŠÛ•Ú†Û•", + "pa-IN": "ÙŸŰ§Ù†ŰŹŰ§ÙŸÚ†Û•", + "pl": "ٟولەكچە", + "pt-BR": "ŰšÙ‰Ű±Ű§ŰČىلىيە ÙŸÙˆŰ±ŰȘÛ‡ÚŻŰ§Ù„Ú†Û•", + "pt-PT": "ÙŠŰ§Û‹Ű±ÙˆÙŸŰ§ ÙŸÙˆŰ±ŰȘÛ‡ÚŻŰ§Ù„Ú†Û•", + "ro-RO": "Ű±ÙˆÙ…Ű§Ù†Ù‰ÙŠÛ•Ù†Ú†Û•", + "ru": "Ű±Û‡ŰłÚ†Û•", + "sk-SK": "ŰłÙ„ÙˆÛ‹Ű§ÙƒÚ†Û•", + "sl-SI": "ŰłÙ‰Ù„ÙˆÛ‹ÛÙ†Ù‰ÙŠÛ•Ú†Û•", + "sq-AL": "ŰŠŰ§Ù„ŰšŰ§Ù†Ú†Û•", + "sr": "ŰłÛŰ±ŰšÚ†Û• (ŰłÛŰ±ŰšÙ‰ÙŠÛ•)", + "sv": "ŰŽÛ‹ÛŰŻÚ†Û• (ŰŽÛ‹ÛŰȘŰłÙ‰ÙŠÛ•)", + "sw": "ŰłÛ‹Ű§ŰźÙ‰Ù„Ù‰Ú†Û•", + "ta-IN": "ŰȘŰ§Ù…Ù‰Ù„Ú†Û•", + "te-IN": "ŰȘÛÙ„Û‡ÚŻÛ‡Ú†Û•", + "th": "ŰȘŰ§ÙŠÙ„Ű§Ù†ŰŻÚ†Û•", + "tl-PH": "فىلىٟىنچە", + "tr": "ŰȘÛˆŰ±ÙƒÚ†Û•", + "ug": "ŰŠÛ‡ÙŠŰșÛ‡Ű±Ú†Û•", + "uk-UA": "ŰŠÛ‡ÙƒŰ±Ű§ŰŠÙ‰Ù†Ű§Ú†Û•", + "ur": "ŰŠÙˆŰ±ŰŻÛ‡Ú†Û•", + "vi": "ۋېيŰȘÙ†Ű§Ù…Ú†Û•", + "yue": "ÚŻÛ‡Ű§Ú­ŰŻÙˆÚ­ ŰŻÙ‰ŰŠŰ§Ù„Ù‰ÙƒÙ‰ŰȘى", + "zh-CN": "ŰźÛ•Ù†ŰČۇچە (ŰŹÛ‡Ú­ÚŻÙˆ)", + "zh-HK": "ŰźÛ•Ù†ŰČۇچە (ŰŽÙ‰ÙŠŰ§Ú­ÚŻŰ§Ú­)", + "zh-Hant": "ŰŠÛ•Ù†ŰŠÛ•Ù†Û‹Ù‰ÙŠ ŰźÛ•Ù†ŰČۇچە" + }, + "uk-UA": { + "af-ZA": "АфроĐșĐ°Đ°ĐœŃ", + "ar": "ĐŃ€Đ°Đ±ŃŃŒĐșа", + "az-AZ": "АзДрбаĐčĐŽĐ¶Đ°ĐœŃŃŒĐșа", + "bg-BG": "Đ‘ĐŸĐ»ĐłĐ°Ń€ŃŃŒĐșа", + "bn-BD": "Đ‘Đ”ĐœĐłĐ°Đ»ŃŒŃŃŒĐșа", + "bs-BA": "Đ‘ĐŸŃĐœŃ–ĐčсьĐșа", + "ca": "ĐšĐ°Ń‚Đ°Đ»ĐŸĐœŃŃŒĐșа", + "cs": "Đ§Đ”ŃŃŒĐșа", + "da": "Đ”Đ°ĐœŃŃŒĐșа", + "de": "ĐŃ–ĐŒĐ”Ń†ŃŒĐșа", + "el": "Đ“Ń€Đ”Ń†ŃŒĐșа", + "en": "ĐĐœĐłĐ»Ń–ĐčсьĐșа", + "es": "Đ†ŃĐżĐ°ĐœŃŃŒĐșа", + "et-EE": "Đ•ŃŃ‚ĐŸĐœŃŃŒĐșа", + "eu": "БасĐșсьĐșа", + "fa-IR": "ĐŸĐ”Ń€ŃŃŒĐșа", + "fi": "Đ€Ń–ĐœŃŃŒĐșа", + "fr": "Đ€Ń€Đ°ĐœŃ†ŃƒĐ·ŃŒĐșа", + "ga-IE": "Đ†Ń€Đ»Đ°ĐœĐŽŃŃŒĐșа", + "gl-ES": "ГалісіĐčсьĐșа", + "gu-IN": "Đ“ŃƒĐŽĐ¶Đ°Ń€Đ°Ń‚Ń–", + "he": "ІĐČрот", + "hi-IN": "Đ“Ń–ĐœĐŽŃ–", + "hr-HR": "Đ„ĐŸŃ€ĐČатсьĐșа", + "hu": "ĐŁĐłĐŸŃ€ŃŃŒĐșа", + "id": "Đ†ĐœĐŽĐŸĐœĐ”Đ·Ń–ĐčсьĐșа", + "it": "ІталіĐčсьĐșа", + "ja": "ĐŻĐżĐŸĐœŃŃŒĐșа", + "ka-GE": "Đ“Ń€ŃƒĐ·ĐžĐœŃŃŒĐșа", + "kk-KZ": "ĐšĐ°Đ·Đ°Ń…ŃŃŒĐșа", + "km-KH": "ĐšŃ…ĐŒĐ”Ń€ŃŃŒĐșа", + "kn-IN": "ĐšĐ°ĐœĐœĐ°ĐŽĐ°", + "ko": "ĐšĐŸŃ€Đ”ĐčсьĐșа", + "ky-KG": "ĐšĐžŃ€ĐłĐžĐ·ŃŒĐșа", + "lt-LT": "Đ›ĐžŃ‚ĐŸĐČсьĐșа", + "lv-LV": "ЛатосьĐșа", + "mk-MK": "МаĐșĐ”ĐŽĐŸĐœŃŃŒĐșа", + "ml-IN": "ĐœĐ°Đ»Đ°ŃĐ»Đ°ĐŒ", + "mr-IN": "Маратхі", + "ms": "ĐœĐ°Đ»Đ°ĐčсьĐșа", + "my": "Đ‘Ń–Ń€ĐŒĐ°ĐœŃŃŒĐșа", + "nb": "ĐĐŸŃ€ĐČĐ”Đ·ŃŒĐșа", + "nl": "ĐŃ–ĐŽĐ”Ń€Đ»Đ°ĐœĐŽŃŃŒĐșа", + "pa-IN": "ĐŸĐ°ĐœĐŽĐ¶Đ°Đ±Ń–", + "pl": "ĐŸĐŸĐ»ŃŒŃŃŒĐșа", + "pt-BR": "Đ‘Ń€Đ°Đ·ĐžĐ»ŃŒŃŃŒĐșа ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃŒŃŃŒĐșа", + "pt-PT": "ЄĐČŃ€ĐŸĐżĐ”ĐčсьĐșа ĐżĐŸŃ€Ń‚ŃƒĐłĐ°Đ»ŃŒŃŃŒĐșа", + "ro-RO": "Đ ŃƒĐŒŃƒĐœŃŃŒĐșа", + "ru": "Đ ĐŸŃŃ–ĐčсьĐșа", + "sk-SK": "ĐĄĐ»ĐŸĐČацьĐșа", + "sl-SI": "ĐĄĐ»ĐŸĐČĐ”ĐœŃŃŒĐșа", + "sq-AL": "ĐĐ»Đ±Đ°ĐœŃŃŒĐșа", + "sr": "ĐĄĐ”Ń€Đ±ŃŃŒĐșа", + "sv": "ĐšĐČĐ”ĐŽŃŃŒĐșа", + "sw": "ĐĄŃƒĐ°Ń…Ń–Đ»Ń–", + "ta-IN": "ĐąĐ°ĐŒŃ–Đ»ŃŒŃŃŒĐșа", + "te-IN": "йДлугу", + "th": "йаĐčсьĐșа", + "tl-PH": "Đ€Ń–Đ»Ń–ĐżĐżŃ–ĐœŃŃŒĐșа", + "tr": "ĐąŃƒŃ€Đ”Ń†ŃŒĐșа", + "ug": "ĐŁĐčгурсьĐșа", + "uk-UA": "ĐŁĐșŃ€Đ°Ń—ĐœŃŃŒĐșа", + "ur": "УрЮу", + "vi": "Đ’ÊŒŃ”Ń‚ĐœĐ°ĐŒŃŃŒĐșа", + "yue": "ĐšĐ°ĐœŃ‚ĐŸĐœŃŃŒĐșа", + "zh-CN": "КотаĐčсьĐșа (КотаĐč)", + "zh-HK": "КотаĐčсьĐșа (Đ“ĐŸĐœĐșĐŸĐœĐł)", + "zh-Hant": "КотаĐčсьĐșа (траЮоціĐčĐœĐ” ĐżĐžŃŃŒĐŒĐŸ)" + }, + "ur": { + "af-ZA": "Ű§ÙŰ±ÛŒÚ©Ű§Ù†ŰČ", + "ar": "ŰčŰ±ŰšÛŒ", + "az-AZ": "ŰąŰ°Ű±ŰšŰ§ŰŠÛŒŰŹŰ§Ù†ÛŒ", + "bg-BG": "ŰšÙ„ŰșŰ§Ű±ÛŒ", + "bn-BD": "ŰšÙ†ÚŻÙ„Û", + "bs-BA": "ŰšÙˆŰłÙ†ÛŒŰ§ŰŠÛŒ", + "ca": "کۧŰȘŰ§Ù„ÙˆÙ†ÛŒŰ§ŰŠÛŒ", + "cs": "چیک", + "da": "ÚˆÛŒÙ†ŰŽ", + "de": "ŰŹŰ±Ù…Ù†", + "el": "ÛŒÙˆÙ†Ű§Ù†ÛŒ", + "en": "Ű§Ù†ÚŻŰ±ÛŒŰČی", + "es": "ÛŰłÙŸŰ§Ù†ÙˆÛŒ", + "et-EE": "ۧ۳Ùčونین", + "eu": "ŰšŰ§ŰłÚ©ÛŒ", + "fa-IR": "ÙŰ§Ű±ŰłÛŒ", + "fi": "ÙÛŒÙ†ŰŽ", + "fr": "ÙŰ±Ű§Ù†ŰłÛŒŰłÛŒ", + "ga-IE": "۹ۊ۱ێ", + "gl-ES": "ÚŻŰ§Ù„ÛŒŰŽÛŒŰ§ŰŠÛŒ", + "gu-IN": "گۏ۱ۧŰȘی", + "he": "ŰčŰšŰ±Ű§Ù†ÛŒ", + "hi-IN": "ÛÙ†ŰŻÛŒ", + "hr-HR": "Ú©Ű±ÙˆÛŒŰŠŰŽÛŒÙ†", + "hu": "ÛÙ†ÚŻÛŒŰ±ÛŒÙ†", + "id": "Ű§Ù†ÚˆÙˆÙ†ÛŒŰŽÛŒŰ§ŰŠÛŒ", + "it": "Ű§Ű·Ű§Ù„ÙˆÛŒ", + "ja": "ŰŹŰ§ÙŸŰ§Ù†ÛŒ", + "ka-GE": "ŰŹŰ§Ű±ŰŹÛŒŰ§ŰŠÛŒ", + "kk-KZ": "Ù‚Ű§ŰČق", + "km-KH": "ŰźÙ…ÛŒŰ±", + "kn-IN": "Ú©Ù†Ù‘Ű§ÚˆŰ§", + "ko": "Ú©ÙˆŰ±ÛŒŰ§ŰŠÛŒ", + "ky-KG": "ک۱ŰșیŰČی", + "lt-LT": "لیŰȘڟوینین", + "lv-LV": "لیÙčوین", + "mk-MK": "Ù…Ù‚ŰŻÙˆÙ†ÛŒŰ§ŰŠÛŒ", + "ml-IN": "Ù…Ù„ÛŒŰ§Ù„Ù…", + "mr-IN": "Ù…Ű±Ű§Ùčهی", + "ms": "Ù…Ű§Ù„Û’", + "my": "ŰšŰ±Ù…ÛŒ", + "nb": "Ù†Ű§Ű±ÙˆÛŒŰŹÛŒÙ† ŰšÙˆÚ©Ù…Ù„", + "nl": "ڈچ", + "pa-IN": "ÙŸÙ†ŰŹŰ§ŰšÛŒ", + "pl": "ÙŸÙˆÙ„ŰŽ", + "pt-BR": "ۚ۱ۧŰČیلی ÙŸŰ±ŰȘÚŻŰ§Ù„ÛŒ", + "pt-PT": "ÛŒÙˆŰ±ÙŸÛŒ ÙŸŰ±ŰȘÚŻŰ§Ù„ÛŒ", + "ro-RO": "Ű±ÙˆÙ…Ű§Ù†ÛŒÙ†", + "ru": "Ű±ÙˆŰłÛŒ", + "sk-SK": "ŰłÙ„ÙˆÙˆŰ§Ú©", + "sl-SI": "ŰłÙ„ÙˆÙˆÛŒÙ†ÛŒŰ§ŰŠÛŒ", + "sq-AL": "Ű§Ù„ŰšŰ§Ù†ÛŒ", + "sr": "ŰłŰ±ŰšÛŒÙ†", + "sv": "ŰłÙˆÛŒÚˆŰŽ", + "sw": "ŰłÙˆŰ§Ű­Ù„ÛŒ", + "ta-IN": "ŰȘمل", + "te-IN": "ŰȘÛŒÙ„ÚŻÙˆ", + "th": "ŰȘÚŸŰ§ŰŠÛŒ", + "tl-PH": "فلیٟینو", + "tr": "ŰȘŰ±Ú©ÛŒ", + "ug": "Ű§ÙˆÛŒŰșÙˆŰ±", + "uk-UA": "ÛŒÙˆÚ©Ű±ÛŒÙ†ÛŒŰ§ŰŠÛŒ", + "ur": "Ű§Ű±ŰŻÙˆ", + "vi": "ویŰȘÙ†Ű§Ù…ÛŒ", + "yue": "کینÙčنی", + "zh-CN": "چینی (چین)", + "zh-HK": "چینی (ÛŰ§Ù†ÚŻ Ú©Ű§Ù†ÚŻ)", + "zh-Hant": "Ű±ÙˆŰ§ÛŒŰȘی چینی" + }, + "vi": { + "af-ZA": "Tiáșżng Afrikaans", + "ar": "Tiáșżng áșą Ráș­p", + "az-AZ": "Tiáșżng Azerbaijan", + "bg-BG": "Tiáșżng Bulgaria", + "bn-BD": "Tiáșżng Bangla", + "bs-BA": "Tiáșżng Bosnia", + "ca": "Tiáșżng Catalan", + "cs": "Tiáșżng SĂ©c", + "da": "Tiáșżng Đan MáșĄch", + "de": "Tiáșżng Đức", + "el": "Tiáșżng Hy LáșĄp", + "en": "Tiáșżng Anh", + "es": "Tiáșżng TĂąy Ban Nha", + "et-EE": "Tiáșżng Estonia", + "eu": "Tiáșżng Basque", + "fa-IR": "Tiáșżng Ba Tư", + "fi": "Tiáșżng Pháș§n Lan", + "fr": "Tiáșżng PhĂĄp", + "ga-IE": "Tiáșżng Ireland", + "gl-ES": "Tiáșżng Galicia", + "gu-IN": "Tiáșżng Gujarat", + "he": "Tiáșżng Do ThĂĄi", + "hi-IN": "Tiáșżng Hindi", + "hr-HR": "Tiáșżng Croatia", + "hu": "Tiáșżng Hungary", + "id": "Tiáșżng Indonesia", + "it": "Tiáșżng Italy", + "ja": "Tiáșżng Nháș­t", + "ka-GE": "Tiáșżng Georgia", + "kk-KZ": "Tiáșżng Kazakh", + "km-KH": "Tiáșżng Khmer", + "kn-IN": "Tiáșżng Kannada", + "ko": "Tiáșżng HĂ n", + "ky-KG": "Tiáșżng Kyrgyz", + "lt-LT": "Tiáșżng Litva", + "lv-LV": "Tiáșżng Latvia", + "mk-MK": "Tiáșżng Macedonia", + "ml-IN": "Tiáșżng Malayalam", + "mr-IN": "Tiáșżng Marathi", + "ms": "Tiáșżng MĂŁ Lai", + "my": "Tiáșżng Miáșżn Điện", + "nb": "Tiáșżng Na Uy", + "nl": "Tiáșżng HĂ  Lan", + "pa-IN": "Tiáșżng Punjab", + "pl": "Tiáșżng Ba Lan", + "pt-BR": "Tiáșżng Bồ Đào Nha (Brazil)", + "pt-PT": "Tiáșżng Bồ Đào Nha (Bồ Đào Nha)", + "ro-RO": "Tiáșżng Romania", + "ru": "Tiáșżng Nga", + "sk-SK": "Tiáșżng Slovak", + "sl-SI": "Tiáșżng Slovenia", + "sq-AL": "Tiáșżng Albania", + "sr": "Tiáșżng Serbia", + "sv": "Tiáșżng ThỄy Điển", + "sw": "Tiáșżng Swahili", + "ta-IN": "Tiáșżng Tamil", + "te-IN": "Tiáșżng Telugu", + "th": "Tiáșżng ThĂĄi", + "tl-PH": "Tiáșżng Philippines", + "tr": "Tiáșżng Thổ NhÄ© Kỳ", + "ug": "Tiáșżng Duy NgĂŽ NhÄ©", + "uk-UA": "Tiáșżng Ukraina", + "ur": "Tiáșżng Urdu", + "vi": "Tiáșżng Việt", + "yue": "Tiáșżng QuáșŁng ĐÎng", + "zh-CN": "Tiáșżng Trung (Trung Quốc)", + "zh-HK": "Tiáșżng Trung (Hồng KĂŽng)", + "zh-Hant": "Tiáșżng Trung Phồn Thể" + }, + "yue": { + "af-ZA": "ć—éžè·è˜­æ–‡", + "ar": "é˜żæ‹‰äŒŻæ–‡", + "az-AZ": "é˜żćĄžæ‹œç–†æ–‡", + "bg-BG": "äżćŠ ćˆ©äșžæ–‡", + "bn-BD": "ć­ŸćŠ æ‹‰æ–‡", + "bs-BA": "æłąæ–Żć°Œäșžæ–‡", + "ca": "ćŠ æł°éš†ć°Œäșžæ–‡", + "cs": "æ·ć…‹æ–‡", + "da": "äžčéș„文", + "de": "ćŸ·æ–‡", + "el": "ćžŒè‡˜æ–‡", + "en": "英文", + "es": "è„żç­ç‰™æ–‡", + "et-EE": "愛æČ™ć°Œäșžæ–‡", + "eu": "ć·Žæ–Żć…‹æ–‡", + "fa-IR": "æłąæ–Żæ–‡", + "fi": "èŠŹè˜­æ–‡", + "fr": "æł•æ–‡", + "ga-IE": "愛爟蘭文", + "gl-ES": "ćŠ ćˆ©è„żäșžæ–‡", + "gu-IN": "ć€ć‰æ‹‰ç‰č文", + "he": "ćžŒäŒŻäŸ†æ–‡", + "hi-IN": "ć°ćœ°æ–‡", + "hr-HR": "ć…‹çŸ…ćœ°äșžæ–‡", + "hu": "ćŒˆç‰™ćˆ©æ–‡", + "id": "ć°ć°Œæ–‡", + "it": "æ„ć€§ćˆ©æ–‡", + "ja": "æ—„æ–‡", + "ka-GE": "æ Œé­Żć‰äșžæ–‡", + "kk-KZ": "ć“ˆè–©ć…‹æ–‡", + "km-KH": "é«˜æŁ‰æ–‡", + "kn-IN": "ćŽçŽé”æ–‡", + "ko": "韓文", + "ky-KG": "ć‰çˆŸć‰æ–Żæ–‡", + "lt-LT": "ç«‹é™¶ćź›æ–‡", + "lv-LV": "拉脫維äșžæ–‡", + "mk-MK": "éŠŹć…¶é “æ–‡", + "ml-IN": "éŠŹæ‹‰é›…æ‹‰ć§†æ–‡", + "mr-IN": "éŠŹæ‹‰ćœ°æ–‡", + "ms": "éŠŹäŸ†æ–‡", + "my": "ç·Źç”žæ–‡", + "nb": "ć·Žć…‹æ‘©æŒȘćšæ–‡", + "nl": "荷蘭文", + "pa-IN": "æ—éźæ™źæ–‡", + "pl": "æłąè˜­æ–‡", + "pt-BR": "ć·Žè„żè‘Ąè„ç‰™æ–‡", + "pt-PT": "歐æŽČè‘Ąè„ç‰™æ–‡", + "ro-RO": "çŸ…éŠŹć°Œäșžæ–‡", + "ru": "äż„æ–‡", + "sk-SK": "æ–ŻæŽ›äŒć…‹æ–‡", + "sl-SI": "æ–ŻæŽ›æ–‡ć°Œäșžæ–‡", + "sq-AL": "é˜żçˆŸć·Žć°Œäșžæ–‡", + "sr": "ćĄžçˆŸç¶­äșžæ–‡", + "sv": "ç‘žć…žæ–‡", + "sw": "ćČç“ŠćžŒćˆ©æ–‡", + "ta-IN": "æł°ç±łçˆŸæ–‡", + "te-IN": "æł°ç›§ć›ș文", + "th": "æł°æ–‡", + "tl-PH": "èČćŸ‹èł“æ–‡", + "tr": "ćœŸè€łć…¶æ–‡", + "ug": "ç¶­ćŸçˆŸæ–‡", + "uk-UA": "çƒć…‹è˜­æ–‡", + "ur": "烏爟郜文", + "vi": "è¶Šć—æ–‡", + "yue": "ć»Łæ±è©±", + "zh-CN": "äž­æ–‡ïŒˆäž­ćœ‹ïŒ‰", + "zh-HK": "äž­æ–‡ïŒˆéŠ™æžŻïŒ‰", + "zh-Hant": "çčé«”äž­æ–‡" + }, + "zh-CN": { + "af-ZA": "ć—éžè·ć…°èŻ­", + "ar": "é˜żæ‹‰äŒŻèŻ­", + "az-AZ": "é˜żćĄžæ‹œç–†èŻ­", + "bg-BG": "äżćŠ ćˆ©äșšèŻ­", + "bn-BD": "ć­ŸćŠ æ‹‰èŻ­", + "bs-BA": "æłąæ–Żć°ŒäșšèŻ­", + "ca": "ćŠ æł°çœ—ć°ŒäșšèŻ­", + "cs": "æ·ć…‹èŻ­", + "da": "äžčéșŠèŻ­", + "de": "ćŸ·èŻ­", + "el": "ćžŒè…ŠèŻ­", + "en": "è‹±èŻ­", + "es": "è„żç­ç‰™èŻ­", + "et-EE": "爱æČ™ć°ŒäșšèŻ­", + "eu": "ć·Žæ–Żć…‹èŻ­", + "fa-IR": "æłąæ–ŻèŻ­", + "fi": "èŠŹć…°èŻ­", + "fr": "æł•èŻ­", + "ga-IE": "çˆ±ć°”ć…°èŻ­", + "gl-ES": "ćŠ ćˆ©è„żäșšèŻ­", + "gu-IN": "ć€ć‰æ‹‰ç‰čèŻ­", + "he": "ćžŒäŒŻæ„èŻ­", + "hi-IN": "ć°ćœ°èŻ­", + "hr-HR": "ć…‹çœ—ćœ°äșšèŻ­", + "hu": "ćŒˆç‰™ćˆ©èŻ­", + "id": "捰ćșŠć°Œè„żäșšèŻ­", + "it": "æ„ć€§ćˆ©èŻ­", + "ja": "æ—„èŻ­", + "ka-GE": "æ Œéȁ搉äșšèŻ­", + "kk-KZ": "ć“ˆèšć…‹èŻ­", + "km-KH": "é«˜æŁ‰èŻ­", + "kn-IN": "捡çșłèŸŸèŻ­", + "ko": "éŸ©èŻ­", + "ky-KG": "æŸŻć°”ć…‹ć­œèŻ­", + "lt-LT": "ç«‹é™¶ćź›èŻ­", + "lv-LV": "拉脱绎äșšèŻ­", + "mk-MK": "é©Źć…¶éĄżèŻ­", + "ml-IN": "é©Źæ‹‰é›…æ‹‰ć§†èŻ­", + "mr-IN": "é©Źæ‹‰ćœ°èŻ­", + "ms": "é©Źæ„èŻ­", + "my": "çŒ…ç”žèŻ­", + "nb": "ć·Žć…‹æ‘©æŒȘćšèŻ­", + "nl": "è·ć…°èŻ­", + "pa-IN": "æ—éźæ™źèŻ­", + "pl": "æłąć…°èŻ­", + "pt-BR": "ć·Žè„żè‘Ąè„ç‰™èŻ­", + "pt-PT": "æŹ§æŽČè‘Ąè„ç‰™èŻ­", + "ro-RO": "çœ—é©Źć°ŒäșšèŻ­", + "ru": "äż„èŻ­", + "sk-SK": "æ–ŻæŽ›äŒć…‹èŻ­", + "sl-SI": "æ–ŻæŽ›æ–‡ć°ŒäșšèŻ­", + "sq-AL": "é˜żć°”ć·Žć°ŒäșšèŻ­", + "sr": "楞气绎äșšèŻ­", + "sv": "ç‘žć…žèŻ­", + "sw": "æ–Żç“ŠćžŒé‡ŒèŻ­", + "ta-IN": "æł°ç±łć°”èŻ­", + "te-IN": "æł°ćąć›șèŻ­", + "th": "æł°èŻ­", + "tl-PH": "èČćŸ‹ćźŸèŻ­", + "tr": "ćœŸè€łć…¶èŻ­", + "ug": "ç»ŽćŸć°”èŻ­", + "uk-UA": "äčŒć…‹ć…°èŻ­", + "ur": "äčŒć°”éƒœèŻ­", + "vi": "è¶Šć—èŻ­", + "yue": "çČ€èŻ­", + "zh-CN": "äž­æ–‡ïŒˆäž­ć›œïŒ‰", + "zh-HK": "äž­æ–‡ïŒˆéŠ™æžŻïŒ‰", + "zh-Hant": "çčäœ“äž­æ–‡" + }, + "zh-HK": { + "af-ZA": "ć—éžè·è˜­æ–‡", + "ar": "é˜żæ‹‰äŒŻæ–‡", + "az-AZ": "é˜żćĄžæ‹œç–†æ–‡", + "bg-BG": "äżćŠ ćˆ©äșžæ–‡", + "bn-BD": "ć­ŸćŠ æ‹‰æ–‡", + "bs-BA": "æłąæ–Żć°Œäșžæ–‡", + "ca": "ćŠ æł°éš†ć°Œäșžæ–‡", + "cs": "æ·ć…‹æ–‡", + "da": "äžčéș„文", + "de": "ćŸ·æ–‡", + "el": "ćžŒè‡˜æ–‡", + "en": "英文", + "es": "è„żç­ç‰™æ–‡", + "et-EE": "愛æČ™ć°Œäșžæ–‡", + "eu": "ć·Žæ–Żć…‹æ–‡", + "fa-IR": "æłąæ–Żæ–‡", + "fi": "èŠŹè˜­æ–‡", + "fr": "æł•æ–‡", + "ga-IE": "愛爟蘭文", + "gl-ES": "ćŠ ćˆ©è„żäșžæ–‡", + "gu-IN": "ć€ć‰æ‹‰ç‰č文", + "he": "ćžŒäŒŻäŸ†æ–‡", + "hi-IN": "ć°ćœ°æ–‡", + "hr-HR": "ć…‹çŸ…ćœ°äșžæ–‡", + "hu": "ćŒˆç‰™ćˆ©æ–‡", + "id": "ć°ć°Œæ–‡", + "it": "æ„ć€§ćˆ©æ–‡", + "ja": "æ—„æ–‡", + "ka-GE": "æ Œé­Żć‰äșžæ–‡", + "kk-KZ": "ć“ˆè–©ć…‹æ–‡", + "km-KH": "é«˜æŁ‰æ–‡", + "kn-IN": "ćŽçŽé”æ–‡", + "ko": "韓文", + "ky-KG": "ć‰çˆŸć‰æ–Żæ–‡", + "lt-LT": "ç«‹é™¶ćź›æ–‡", + "lv-LV": "拉脫維äșžæ–‡", + "mk-MK": "éŠŹć…¶é “æ–‡", + "ml-IN": "éŠŹæ‹‰é›…æ‹‰ć§†æ–‡", + "mr-IN": "éŠŹæ‹‰ćœ°æ–‡", + "ms": "éŠŹäŸ†æ–‡", + "my": "ç·Źç”žæ–‡", + "nb": "ć·Žć…‹æ‘©æŒȘćšæ–‡", + "nl": "荷蘭文", + "pa-IN": "æ—éźæ™źæ–‡", + "pl": "æłąè˜­æ–‡", + "pt-BR": "ć·Žè„żè‘Ąè„ç‰™æ–‡", + "pt-PT": "歐æŽČè‘Ąè„ç‰™æ–‡", + "ro-RO": "çŸ…éŠŹć°Œäșžæ–‡", + "ru": "äż„æ–‡", + "sk-SK": "æ–ŻæŽ›äŒć…‹æ–‡", + "sl-SI": "æ–ŻæŽ›æ–‡ć°Œäșžæ–‡", + "sq-AL": "é˜żçˆŸć·Žć°Œäșžæ–‡", + "sr": "ćĄžçˆŸç¶­äșžæ–‡", + "sv": "ç‘žć…žæ–‡", + "sw": "ćČç“ŠćžŒćˆ©æ–‡", + "ta-IN": "æł°ç±łçˆŸæ–‡", + "te-IN": "æł°ç›§ć›ș文", + "th": "æł°æ–‡", + "tl-PH": "èČćŸ‹èł“æ–‡", + "tr": "ćœŸè€łć…¶æ–‡", + "ug": "ç¶­ćŸçˆŸæ–‡", + "uk-UA": "çƒć…‹è˜­æ–‡", + "ur": "烏爟郜文", + "vi": "è¶Šć—æ–‡", + "yue": "ć»Łæ±è©±", + "zh-CN": "äž­æ–‡ïŒˆäž­ćœ‹ïŒ‰", + "zh-HK": "äž­æ–‡ïŒˆéŠ™æžŻïŒ‰", + "zh-Hant": "çčé«”äž­æ–‡" + }, + "zh-Hant": { + "af-ZA": "ć—éžè·è˜­æ–‡", + "ar": "é˜żæ‹‰äŒŻæ–‡", + "az-AZ": "äșžćĄžæ‹œç„¶æ–‡", + "bg-BG": "äżćŠ ćˆ©äșžæ–‡", + "bn-BD": "ć­ŸćŠ æ‹‰æ–‡", + "bs-BA": "æłąćŁ«ć°Œäșžæ–‡", + "ca": "ćŠ æł°è˜­æ–‡", + "cs": "æ·ć…‹æ–‡", + "da": "äžčéș„文", + "de": "ćŸ·æ–‡", + "el": "ćžŒè‡˜æ–‡", + "en": "英文", + "es": "è„żç­ç‰™æ–‡", + "et-EE": "愛æČ™ć°Œäșžæ–‡", + "eu": "ć·Žæ–Żć…‹æ–‡", + "fa-IR": "æłąæ–Żæ–‡", + "fi": "èŠŹè˜­æ–‡", + "fr": "æł•æ–‡", + "ga-IE": "愛爟蘭文", + "gl-ES": "ćŠ ćˆ©è„żäșžæ–‡", + "gu-IN": "ć€ć‰æ‹‰ç‰č文", + "he": "ćžŒäŒŻäŸ†æ–‡", + "hi-IN": "ć°ćœ°æ–‡", + "hr-HR": "ć…‹çŸ…ćŸƒè„żäșžæ–‡", + "hu": "ćŒˆç‰™ćˆ©æ–‡", + "id": "ć°ć°Œæ–‡", + "it": "çŸ©ć€§ćˆ©æ–‡", + "ja": "æ—„æ–‡", + "ka-GE": "斬æČ»äșžæ–‡", + "kk-KZ": "ć“ˆè–©ć…‹æ–‡", + "km-KH": "é«˜æŁ‰æ–‡", + "kn-IN": "ćŽé‚Łé”æ–‡", + "ko": "韓文", + "ky-KG": "ć‰çˆŸć‰æ–Żæ–‡", + "lt-LT": "ç«‹é™¶ćź›æ–‡", + "lv-LV": "拉脫維äșžæ–‡", + "mk-MK": "éŠŹć…¶é “æ–‡", + "ml-IN": "éŠŹäŸ†äșžæ‹‰ć§†æ–‡", + "mr-IN": "éŠŹæ‹‰ćœ°æ–‡", + "ms": "éŠŹäŸ†æ–‡", + "my": "ç·Źç”žæ–‡", + "nb": "ć·Žć…‹æ‘©æŒȘćšæ–‡", + "nl": "荷蘭文", + "pa-IN": "æ—éźæ™źæ–‡", + "pl": "æłąè˜­æ–‡", + "pt-BR": "è‘Ąè„ç‰™æ–‡ïŒˆć·Žè„żïŒ‰", + "pt-PT": "è‘Ąè„ç‰™æ–‡ïŒˆè‘Ąè„ç‰™ïŒ‰", + "ro-RO": "çŸ…éŠŹć°Œäșžæ–‡", + "ru": "äż„æ–‡", + "sk-SK": "æ–ŻæŽ›äŒć…‹æ–‡", + "sl-SI": "æ–ŻæŽ›ç¶­ć°Œäșžæ–‡", + "sq-AL": "é˜żçˆŸć·Žć°Œäșžæ–‡", + "sr": "ćĄžçˆŸç¶­äșžæ–‡", + "sv": "ç‘žć…žæ–‡", + "sw": "ćČç“ŠćžŒćˆ©æ–‡", + "ta-IN": "ćŠç±łçˆŸæ–‡", + "te-IN": "æł°ç›§ć›ș文", + "th": "æł°æ–‡", + "tl-PH": "èČćŸ‹èł“æ–‡", + "tr": "ćœŸè€łć…¶æ–‡", + "ug": "ç¶­ćŸçˆŸæ–‡", + "uk-UA": "çƒć…‹è˜­æ–‡", + "ur": "烏郜文", + "vi": "è¶Šć—æ–‡", + "yue": "çČ”èȘž", + "zh-CN": "äž­æ–‡ïŒˆäž­ćœ‹ïŒ‰", + "zh-HK": "äž­æ–‡ïŒˆéŠ™æžŻïŒ‰", + "zh-Hant": "çčé«”äž­æ–‡" + } +} \ No newline at end of file diff --git a/config/default.json b/config/default.json index 392d868d1c..59fb06ce22 100644 --- a/config/default.json +++ b/config/default.json @@ -13,7 +13,7 @@ "resourcesUrl": "https://updates2.signal.org", "artCreatorUrl": "https://create.staging.signal.art", "updatesPublicKey": "05fd7dd3de7149dc0a127909fee7de0f7620ddd0de061b37a2c303e37de802a401", - "sfuUrl": "https://sfu.voip.signal.org/", + "sfuUrl": "https://sfu.staging.voip.signal.org/", "challengeUrl": "https://signalcaptchas.org/staging/challenge/generate.html", "registrationChallengeUrl": "https://signalcaptchas.org/staging/registration/generate.html", "updatesEnabled": false, diff --git a/config/production.json b/config/production.json index 72919ab13b..5f931c6e2d 100644 --- a/config/production.json +++ b/config/production.json @@ -9,6 +9,7 @@ "3": "https://cdn3.signal.org" }, "artCreatorUrl": "https://create.signal.art", + "sfuUrl": "https://sfu.voip.signal.org/", "challengeUrl": "https://signalcaptchas.org/challenge/generate.html", "registrationChallengeUrl": "https://signalcaptchas.org/registration/generate.html", "serverPublicParams": "AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXTLfN0/vLt98KDPnxwAQL9j5V1jGOY8jQl6MLxEs56cwXN0dqCnImzVH3TZT1cJ8SW1BRX6qIVxEzjsSGx3yxF3suAilPMqGRp4ffyopjMD1JXiKR2RwLKzizUe5e8XyGOy9fplzhw3jVzTRyUZTRSZKkMLWcQ/gv0E4aONNqs4P", diff --git a/images/icons/v3/chat/chat-fill.svg b/images/icons/v3/chat/chat-fill.svg new file mode 100644 index 0000000000..ea4410b45f --- /dev/null +++ b/images/icons/v3/chat/chat-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/filter/filter.svg b/images/icons/v3/filter/filter.svg new file mode 100644 index 0000000000..2fbe7d54e9 --- /dev/null +++ b/images/icons/v3/filter/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/globe/globe.svg b/images/icons/v3/globe/globe.svg new file mode 100644 index 0000000000..e67b012d6d --- /dev/null +++ b/images/icons/v3/globe/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/grid/overflow_view.svg b/images/icons/v3/grid/overflow_view.svg new file mode 100644 index 0000000000..31ed17fe09 --- /dev/null +++ b/images/icons/v3/grid/overflow_view.svg @@ -0,0 +1 @@ + diff --git a/images/icons/v3/menu/menu.svg b/images/icons/v3/menu/menu.svg new file mode 100644 index 0000000000..ea40377d88 --- /dev/null +++ b/images/icons/v3/menu/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/phone/phone-plus-light.svg b/images/icons/v3/phone/phone-plus-light.svg new file mode 100644 index 0000000000..296632db70 --- /dev/null +++ b/images/icons/v3/phone/phone-plus-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/photo/phone-fill.svg b/images/icons/v3/photo/phone-fill.svg new file mode 100644 index 0000000000..d64465d12e --- /dev/null +++ b/images/icons/v3/photo/phone-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/photo/phone.svg b/images/icons/v3/photo/phone.svg new file mode 100644 index 0000000000..3bc73836a4 --- /dev/null +++ b/images/icons/v3/photo/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/raise_hand/raise_hand-bold.svg b/images/icons/v3/raise_hand/raise_hand-bold.svg new file mode 100644 index 0000000000..07159b7af1 --- /dev/null +++ b/images/icons/v3/raise_hand/raise_hand-bold.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/raise_hand/raise_hand-compact-bold.svg b/images/icons/v3/raise_hand/raise_hand-compact-bold.svg new file mode 100644 index 0000000000..85adcafc8d --- /dev/null +++ b/images/icons/v3/raise_hand/raise_hand-compact-bold.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/raise_hand/raise_hand-compact-light.svg b/images/icons/v3/raise_hand/raise_hand-compact-light.svg new file mode 100644 index 0000000000..356158139b --- /dev/null +++ b/images/icons/v3/raise_hand/raise_hand-compact-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/raise_hand/raise_hand-compact.svg b/images/icons/v3/raise_hand/raise_hand-compact.svg new file mode 100644 index 0000000000..d7dba09d48 --- /dev/null +++ b/images/icons/v3/raise_hand/raise_hand-compact.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/raise_hand/raise_hand-light.svg b/images/icons/v3/raise_hand/raise_hand-light.svg new file mode 100644 index 0000000000..7305080ab0 --- /dev/null +++ b/images/icons/v3/raise_hand/raise_hand-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/raise_hand/raise_hand.svg b/images/icons/v3/raise_hand/raise_hand.svg new file mode 100644 index 0000000000..f4dd5b9200 --- /dev/null +++ b/images/icons/v3/raise_hand/raise_hand.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/icons/v3/stories/stories-fill.svg b/images/icons/v3/stories/stories-fill.svg new file mode 100644 index 0000000000..6c7002405d --- /dev/null +++ b/images/icons/v3/stories/stories-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package.json b/package.json index 6584215576..ed1aeb8c4a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Private messaging from your desktop", "desktopName": "signal.desktop", "repository": "https://github.com/signalapp/Signal-Desktop.git", - "version": "6.29.0-beta.1", + "version": "6.44.0-alpha.1", "license": "AGPL-3.0-only", "author": { "name": "Signal Messenger, LLC", @@ -23,12 +23,12 @@ "build-release": "yarn run build", "sign-release": "node ts/updater/generateSignature.js", "notarize": "echo 'No longer necessary'", - "get-strings": "node ts/scripts/get-strings.js && node ts/scripts/gen-nsis-script.js && node ts/scripts/gen-locales-config.js", + "get-strings": "ts-node ts/scripts/get-strings.ts && ts-node ts/scripts/gen-nsis-script.ts && ts-node ts/scripts/gen-locales-config.ts && ts-node ./ts/scripts/build-locale-display-names.ts", "push-strings": "node ts/scripts/remove-strings.js && node ts/scripts/push-strings.js", "get-expire-time": "node ts/scripts/get-expire-time.js", "copy-components": "node ts/scripts/copy.js", "sass": "sass stylesheets/manifest.scss:stylesheets/manifest.css stylesheets/manifest_bridge.scss:stylesheets/manifest_bridge.css", - "build-module-protobuf": "pbjs --target static-module --force-long --no-typeurl --no-verify --no-create --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", + "build-module-protobuf": "pbjs --target static-module --force-long --no-typeurl --no-verify --no-create --no-convert --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --no-comments --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "build-protobuf": "yarn build-module-protobuf", "clean-protobuf": "yarn clean-module-protobuf", @@ -40,8 +40,8 @@ "test": "yarn test-node && yarn test-electron && yarn test-lint-intl && yarn test-eslint", "test-electron": "node ts/scripts/test-electron.js", "test-release": "node ts/scripts/test-release.js", - "test-node": "electron-mocha --timeout 10000 --file test/setup-test-node.js --recursive test/modules ts/test-node ts/test-both", - "test-mock": "mocha ts/test-mock/**/*_test.js", + "test-node": "cross-env LANG=en-us electron-mocha --timeout 10000 --file test/setup-test-node.js --recursive test/modules ts/test-node ts/test-both", + "test-mock": "mocha --require ts/test-mock/setup-ci.js ts/test-mock/**/*_test.js", "test-eslint": "mocha .eslint/rules/**/*.test.js --ignore-leaks", "test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/modules ts/test-node ts/test-both", "test-lint-intl": "ts-node ./build/intl-linter/linter.ts --test", @@ -62,12 +62,16 @@ "clean-transpile": "yarn run clean-transpile-once && yarn run clean-transpile-once", "open-coverage": "open coverage/lcov-report/index.html", "ready": "npm-run-all --print-label clean-transpile generate --parallel lint lint-deps lint-intl test-node test-electron", - "dev": "run-p --print-label dev:*", + "dev": "yarn build-protobuf && cross-env SIGNAL_ENV=storybook storybook dev --port 6006", "dev:transpile": "run-p \"check:types --watch\" dev:esbuild", "dev:esbuild": "node scripts/esbuild.js --watch", - "dev:storybook": "cross-env SIGNAL_ENV=storybook start-storybook -p 6006 -s ./", "dev:sass": "yarn sass --watch", + "build:storybook": "yarn build-protobuf && cross-env SIGNAL_ENV=storybook storybook build", + "test:storybook": "yarn build:storybook && run-p --race test:storybook:*", + "test:storybook:serve": "http-server storybook-static --port 6006 --silent", + "test:storybook:test": "wait-on http://127.0.0.1:6006/ --timeout 5000 && test-storybook", "build": "run-s --print-label generate build:esbuild:prod build:release", + "build-linux": "yarn generate && yarn build:esbuild:prod && yarn build:release -- --publish=never", "build:acknowledgments": "node scripts/generate-acknowledgments.js", "build:dev": "run-s --print-label generate build:esbuild:prod", "build:esbuild": "node scripts/esbuild.js", @@ -89,10 +93,12 @@ "@nodert-win10-rs4/windows.data.xml.dom": "0.4.4", "@nodert-win10-rs4/windows.ui.notifications": "0.4.4", "@popperjs/core": "2.11.6", + "@react-aria/utils": "3.16.0", "@react-spring/web": "9.5.5", - "@signalapp/better-sqlite3": "8.4.3", - "@signalapp/libsignal-client": "0.29.1", - "@signalapp/ringrtc": "2.29.1", + "@signalapp/better-sqlite3": "8.6.0", + "@signalapp/libsignal-client": "0.36.0", + "@signalapp/ringrtc": "2.34.5", + "@signalapp/windows-dummy-keystroke": "1.0.0", "@types/fabric": "4.5.3", "backbone": "1.4.0", "blob-util": "2.0.2", @@ -123,7 +129,6 @@ "google-libphonenumber": "3.2.27", "got": "11.8.5", "heic-convert": "1.2.4", - "history": "4.9.0", "humanize-duration": "3.27.1", "intl-tel-input": "17.0.13", "js-yaml": "3.13.1", @@ -146,11 +151,13 @@ "pify": "3.0.0", "pino": "8.6.1", "protobufjs": "7.2.4", - "proxy-agent": "5.0.0", + "proxy-agent": "6.3.0", "qrcode-generator": "1.4.4", "quill": "1.3.7", "quill-delta": "4.0.1", "react": "17.0.2", + "react-aria": "3.24.0", + "react-aria-components": "1.0.0-alpha.3", "react-blurhash": "0.1.2", "react-contextmenu": "2.11.0", "react-dom": "17.0.2", @@ -174,40 +181,41 @@ "semver": "5.7.2", "split2": "4.0.0", "type-fest": "3.5.0", + "urlpattern-polyfill": "9.0.0", "uuid": "3.3.2", "uuid-browser": "3.1.0", "websocket": "1.0.34", - "@signalapp/windows-dummy-keystroke": "1.0.0", - "zod": "3.5.1" + "zod": "3.21.4" }, "devDependencies": { - "@babel/core": "7.14.3", - "@babel/plugin-proposal-class-properties": "7.17.12", - "@babel/plugin-proposal-nullish-coalescing-operator": "7.17.12", - "@babel/plugin-proposal-optional-chaining": "7.17.12", - "@babel/plugin-transform-runtime": "7.18.2", - "@babel/plugin-transform-typescript": "7.18.4", - "@babel/preset-react": "7.17.12", - "@babel/preset-typescript": "7.17.12", + "@babel/core": "7.23.0", + "@babel/plugin-proposal-class-properties": "7.18.6", + "@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6", + "@babel/plugin-proposal-optional-chaining": "7.21.0", + "@babel/plugin-transform-runtime": "7.22.15", + "@babel/plugin-transform-typescript": "7.22.15", + "@babel/preset-react": "7.22.15", + "@babel/preset-typescript": "7.23.0", "@electron/fuses": "1.5.0", + "@electron/notarize": "2.1.0", "@formatjs/intl": "2.6.7", "@mixer/parallel-prettier": "2.0.3", - "@signalapp/mock-server": "3.2.3", - "@storybook/addon-a11y": "6.5.6", - "@storybook/addon-actions": "6.5.6", - "@storybook/addon-controls": "6.5.6", - "@storybook/addon-interactions": "6.5.9", - "@storybook/addon-knobs": "6.4.0", - "@storybook/addon-measure": "6.5.6", - "@storybook/addon-toolbars": "6.5.6", - "@storybook/addon-viewport": "6.5.6", - "@storybook/addons": "6.5.6", - "@storybook/builder-webpack5": "6.5.15", - "@storybook/jest": "0.0.10", - "@storybook/manager-webpack5": "6.5.15", - "@storybook/react": "6.5.6", - "@storybook/testing-library": "0.0.13", - "@types/backbone": "1.4.5", + "@signalapp/mock-server": "4.3.0", + "@storybook/addon-a11y": "7.4.5", + "@storybook/addon-actions": "7.4.5", + "@storybook/addon-controls": "7.4.5", + "@storybook/addon-interactions": "7.4.5", + "@storybook/addon-jest": "7.4.5", + "@storybook/addon-measure": "7.4.5", + "@storybook/addon-toolbars": "7.4.5", + "@storybook/addon-viewport": "7.4.5", + "@storybook/addons": "7.4.5", + "@storybook/jest": "0.2.2", + "@storybook/react": "7.4.5", + "@storybook/react-webpack5": "7.4.5", + "@storybook/test-runner": "0.13.0", + "@storybook/testing-library": "0.2.2", + "@types/backbone": "1.4.16", "@types/blueimp-load-image": "5.14.1", "@types/chai": "4.2.18", "@types/chai-as-promised": "7.1.4", @@ -255,7 +263,7 @@ "asar": "3.1.0", "axe-core": "4.1.4", "babel-core": "7.0.0-bridge.0", - "babel-loader": "8.0.6", + "babel-loader": "9.1.3", "babel-plugin-lodash": "3.3.4", "casual": "1.6.2", "chai": "4.3.4", @@ -264,12 +272,12 @@ "core-js": "2.6.9", "cross-env": "5.2.0", "css-loader": "3.2.0", + "csv-parse": "5.5.2", "danger": "11.1.2", "debug": "4.3.3", - "electron": "25.4.0", - "electron-builder": "23.0.8", + "electron": "27.1.3", + "electron-builder": "24.6.3", "electron-mocha": "11.0.2", - "electron-notarize": "1.2.1", "endanger": "7.0.4", "esbuild": "0.17.11", "eslint": "8.30.0", @@ -282,19 +290,23 @@ "eslint-plugin-react": "7.31.10", "execa": "5.1.1", "html-webpack-plugin": "5.3.1", + "http-server": "14.1.1", "json-to-ast": "2.1.0", + "mini-css-extract-plugin": "2.7.6", "mocha": "9.1.3", - "node-gyp": "9.0.0", + "node-gyp": "10.0.1", "npm-run-all": "4.1.5", "nyc": "11.4.1", "p-limit": "3.1.0", - "patch-package": "6.4.7", + "patch-package": "8.0.0", "playwright": "1.33.0", "prettier": "2.8.0", "protobufjs-cli": "1.1.1", + "resolve-url-loader": "5.0.0", "sass": "1.49.7", "sass-loader": "10.2.0", "sinon": "11.1.1", + "storybook": "7.4.5", "style-loader": "1.0.0", "stylelint": "15.4.0", "stylelint-config-css-modules": "4.2.0", @@ -306,7 +318,8 @@ "ts-node": "8.3.0", "typed-scss-modules": "4.1.1", "typescript": "5.1.3", - "webpack": "5.76.0", + "wait-on": "7.0.1", + "webpack": "5.88.2", "webpack-cli": "4.9.2", "webpack-dev-server": "4.11.1" }, @@ -322,7 +335,7 @@ "read-last-lines/mz/thenify-all/thenify": "3.3.1" }, "engines": { - "node": "18.15.0" + "node": "18.17.1" }, "build": { "appId": "org.whispersystems.signal-desktop", @@ -343,7 +356,7 @@ "mergeASARs": true, "releaseInfo": { "vendor": { - "minOSVersion": "17.0.0" + "minOSVersion": "19.0.0" } }, "singleArchFiles": "node_modules/@signalapp/{libsignal-client/prebuilds/**,ringrtc/build/**}", @@ -373,6 +386,7 @@ "signingHashAlgorithms": [ "sha256" ], + "sign": "./ts/scripts/sign-windows.js", "publisherName": "Signal Messenger, LLC", "icon": "build/icons/win/icon.ico", "publish": [ @@ -387,6 +401,9 @@ } }, "signDlls": true, + "signExts": [ + ".node" + ], "target": [ "nsis" ] @@ -403,7 +420,8 @@ "target": [ "deb" ], - "icon": "build/icons/png" + "icon": "build/icons/png", + "publish": [] }, "deb": { "depends": [ @@ -412,7 +430,10 @@ "libnss3", "libasound2", "libxss1", - "libc6 (>= 2.31)" + "libc6 (>= 2.31)", + "libgtk-3-0", + "libgbm1", + "libx11-xcb1" ] }, "protocols": { @@ -422,8 +443,8 @@ "signalcaptcha" ] }, - "afterPack": "ts/scripts/after-pack.js", "afterSign": "ts/scripts/after-sign.js", + "afterPack": "ts/scripts/after-pack.js", "afterAllArtifactBuild": "ts/scripts/after-all-artifact-build.js", "asar": { "smartUnpack": false @@ -475,6 +496,7 @@ "sounds/*", "build/icons", "build/available-locales.json", + "build/locale-display-names.json", "node_modules/**", "!node_modules/underscore/**", "!node_modules/emoji-datasource/emoji_pretty.json", @@ -482,6 +504,8 @@ "!node_modules/emoji-datasource-apple/emoji_pretty.json", "!node_modules/emoji-datasource-apple/img/apple/sheets*", "!node_modules/spellchecker/vendor/hunspell/**/*", + "!node_modules/@formatjs/intl-displaynames/**/*", + "!node_modules/@formatjs/intl-listformat/**/*", "!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme,test,__tests__,tests,powered-test,example,examples,*.d.ts,.snyk-*.flag,benchmark}", "!**/node_modules/.bin", "!**/node_modules/**/build/**", diff --git a/patches/@storybook+manager-api+7.4.5.patch b/patches/@storybook+manager-api+7.4.5.patch new file mode 100644 index 0000000000..ecba613a45 --- /dev/null +++ b/patches/@storybook+manager-api+7.4.5.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@storybook/manager-api/dist/index.d.ts b/node_modules/@storybook/manager-api/dist/index.d.ts +index 7afb86e..a15b801 100644 +--- a/node_modules/@storybook/manager-api/dist/index.d.ts ++++ b/node_modules/@storybook/manager-api/dist/index.d.ts +@@ -822,7 +822,7 @@ declare class ManagerProvider extends Component { + static getDerivedStateFromProps(props: ManagerProviderProps, state: State): State; + shouldComponentUpdate(nextProps: ManagerProviderProps, nextState: State): boolean; + initModules: () => void; +- render(): React.JSX.Element; ++ render(): JSX.Element; + } + interface ManagerConsumerProps

{ + filter?: (combo: Combo) => P; diff --git a/patches/@storybook+router+7.4.5.patch b/patches/@storybook+router+7.4.5.patch new file mode 100644 index 0000000000..793a975dbe --- /dev/null +++ b/patches/@storybook+router+7.4.5.patch @@ -0,0 +1,22 @@ +diff --git a/node_modules/@storybook/router/dist/index.d.ts b/node_modules/@storybook/router/dist/index.d.ts +index ed699f7..71f48eb 100644 +--- a/node_modules/@storybook/router/dist/index.d.ts ++++ b/node_modules/@storybook/router/dist/index.d.ts +@@ -335,7 +335,7 @@ declare const useNavigate: () => (to: To | number, { plain, ...options }?: any) + * A component that will navigate to a new location/path when clicked + */ + declare const Link: { +- ({ to, children, ...rest }: LinkProps): React__default.JSX.Element; ++ ({ to, children, ...rest }: LinkProps): JSX.Element; + displayName: string; + }; + /** +@@ -343,7 +343,7 @@ declare const Link: { + * and will be called whenever it changes when it changes + */ + declare const Location: { +- ({ children }: LocationProps): React__default.JSX.Element; ++ ({ children }: LocationProps): JSX.Element; + displayName: string; + }; + /** diff --git a/patches/@types+backbone+1.4.16.patch b/patches/@types+backbone+1.4.16.patch new file mode 100644 index 0000000000..ed2430deb1 --- /dev/null +++ b/patches/@types+backbone+1.4.16.patch @@ -0,0 +1,49 @@ +diff --git a/node_modules/@types/backbone/index.d.ts b/node_modules/@types/backbone/index.d.ts +index 3935075..22a4c2e 100644 +--- a/node_modules/@types/backbone/index.d.ts ++++ b/node_modules/@types/backbone/index.d.ts +@@ -81,7 +81,7 @@ declare namespace Backbone { + collection?: Collection | undefined; + } + +- type CombinedModelConstructorOptions = Model> = ModelConstructorOptions & E; ++ type CombinedModelConstructorOptions = Model> = ModelConstructorOptions & E; + + interface ModelSetOptions extends Silenceable, Validable {} + +@@ -219,7 +219,7 @@ declare namespace Backbone { + */ + static extend(properties: any, classProperties?: any): any; + +- attributes: Partial; ++ attributes: T; + changed: Partial; + cidPrefix: string; + cid: string; +@@ -235,7 +235,7 @@ declare namespace Backbone { + * That works only if you set it in the constructor or the initialize method. + */ + defaults(): Partial; +- id: string | number; ++ id: string; + idAttribute: string; + validationError: any; + +@@ -266,7 +266,7 @@ declare namespace Backbone { + * return super.get("name"); + * } + */ +- get>(attributeName: A): T[A] | undefined; ++ get>(attributeName: A): T[A]; + + /** + * For strongly-typed assignment of attributes, use the `set` method only privately in public setter properties. +@@ -300,7 +300,7 @@ declare namespace Backbone { + previousAttributes(): Partial; + save(attributes?: Partial | null, options?: ModelSaveOptions): JQueryXHR; + unset(attribute: _StringKey, options?: Silenceable): this; +- validate(attributes: Partial, options?: any): any; ++ validate(attributes: T, options?: any): any; + private _validate(attributes: Partial, options: any): boolean; + + // mixins from underscore diff --git a/patches/@types+backbone+1.4.5.patch b/patches/@types+backbone+1.4.5.patch deleted file mode 100644 index 57bfcd8a8a..0000000000 --- a/patches/@types+backbone+1.4.5.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/node_modules/@types/backbone/index.d.ts b/node_modules/@types/backbone/index.d.ts -index a172230..2c62e92 100644 ---- a/node_modules/@types/backbone/index.d.ts -+++ b/node_modules/@types/backbone/index.d.ts -@@ -81,7 +81,7 @@ declare namespace Backbone { - collection?: Backbone.Collection; - } - -- type CombinedModelConstructorOptions = Model> = ModelConstructorOptions & E; -+ type CombinedModelConstructorOptions = Model> = ModelConstructorOptions & E; - - interface ModelSetOptions extends Silenceable, Validable { - } -@@ -218,14 +218,14 @@ declare namespace Backbone { - * E - Extensions to the model constructor options. You can accept additional constructor options - * by listing them in the E parameter. - */ -- class Model extends ModelBase implements Events { -+ class Model = any, S = Backbone.ModelSetOptions, E = {}> extends ModelBase implements Events { - - /** - * Do not use, prefer TypeScript's extend functionality. - **/ - public static extend(properties: any, classProperties?: any): any; - -- attributes: any; -+ attributes: T; - changed: any[]; - cidPrefix: string; - cid: string; diff --git a/patches/@types+express+4.17.13.patch b/patches/@types+express+4.17.18.patch similarity index 100% rename from patches/@types+express+4.17.13.patch rename to patches/@types+express+4.17.18.patch diff --git a/patches/@types+jest+28.1.1.patch b/patches/@types+jest+28.1.3.patch similarity index 94% rename from patches/@types+jest+28.1.1.patch rename to patches/@types+jest+28.1.3.patch index b33bddd34a..77ea181e8e 100644 --- a/patches/@types+jest+28.1.1.patch +++ b/patches/@types+jest+28.1.3.patch @@ -1,10 +1,10 @@ diff --git a/node_modules/@types/jest/index.d.ts b/node_modules/@types/jest/index.d.ts -index 272822a..87ebd1f 100755 +index b37b188..1908c0c 100755 --- a/node_modules/@types/jest/index.d.ts +++ b/node_modules/@types/jest/index.d.ts @@ -30,18 +30,18 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - // Minimum TypeScript Version: 3.8 + // Minimum TypeScript Version: 4.3 -declare var beforeAll: jest.Lifecycle; -declare var beforeEach: jest.Lifecycle; diff --git a/patches/app-builder-lib+23.0.8.patch b/patches/app-builder-lib+24.6.3.patch similarity index 64% rename from patches/app-builder-lib+23.0.8.patch rename to patches/app-builder-lib+24.6.3.patch index f69a2d60f1..abd3142865 100644 --- a/patches/app-builder-lib+23.0.8.patch +++ b/patches/app-builder-lib+24.6.3.patch @@ -1,8 +1,8 @@ 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 +index fcb7f54..3f27bf3 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 { +@@ -99,7 +99,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) { @@ -11,28 +11,13 @@ index ffcc8bd..bafab0e 100644 } } const desktopMeta = { -diff --git a/node_modules/app-builder-lib/scheme.json b/node_modules/app-builder-lib/scheme.json -index 4ce62d9..aea0e0b 100644 ---- a/node_modules/app-builder-lib/scheme.json -+++ b/node_modules/app-builder-lib/scheme.json -@@ -4749,6 +4749,10 @@ - "null", - "string" - ] -+ }, -+ "vendor": { -+ "description": "Vendor-specific informaton", -+ "type": "object" - } - }, - "type": "object" 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 +index 0f541f9..d1e77a0 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}' +@@ -10,8 +10,5 @@ else + ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}' + fi -# SUID chrome-sandbox for Electron 5+ -chmod 4755 '/opt/${sanitizedProductName}/chrome-sandbox' || true @@ -40,10 +25,10 @@ index 1536059..555f8f5 100644 update-mime-database /usr/share/mime || true update-desktop-database /usr/share/applications || true diff --git a/node_modules/app-builder-lib/templates/nsis/installSection.nsh b/node_modules/app-builder-lib/templates/nsis/installSection.nsh -index 96f913a..ee95419 100644 +index 053772f..7981a4e 100644 --- a/node_modules/app-builder-lib/templates/nsis/installSection.nsh +++ b/node_modules/app-builder-lib/templates/nsis/installSection.nsh -@@ -22,10 +22,37 @@ StrCpy $appExe "$INSTDIR\${APP_EXECUTABLE_FILENAME}" +@@ -22,11 +22,38 @@ StrCpy $appExe "$INSTDIR\${APP_EXECUTABLE_FILENAME}" SpiderBanner::Show /MODERN !endif @@ -52,6 +37,7 @@ index 96f913a..ee95419 100644 FindWindow $0 "#32770" "" $hwndparent $0 - GetDlgItem $0 $0 1000 - SendMessage $0 ${WM_SETTEXT} 0 "STR:$(installing)" + + GetDlgItem $1 $0 1000 + SendMessage $1 ${WM_SETTEXT} 0 "STR:$(installing)" + @@ -80,19 +66,6 @@ index 96f913a..ee95419 100644 + GetDlgItem $1 $0 1025 + SendMessage $1 ${STM_SETIMAGE} ${IMAGE_ICON} $2 + !endif + StrCpy $1 $hwndparent + System::Call 'user32::ShutdownBlockReasonCreate(${SYSTYPE_PTR}r1, w "$(installing)")' ${endif} - !insertmacro CHECK_APP_RUNNING - !else -diff --git a/node_modules/app-builder-lib/templates/nsis/messages.yml b/node_modules/app-builder-lib/templates/nsis/messages.yml -index 87fa6b5..ad560bd 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 d’utilisation. \nCliquez sur «OK» pour fermer ce programme." diff --git a/patches/proxy-agent+6.3.0.patch b/patches/proxy-agent+6.3.0.patch new file mode 100644 index 0000000000..eec8d0f0e0 --- /dev/null +++ b/patches/proxy-agent+6.3.0.patch @@ -0,0 +1,12 @@ +diff --git a/node_modules/proxy-agent/dist/index.js b/node_modules/proxy-agent/dist/index.js +index 885d22a..2930652 100644 +--- a/node_modules/proxy-agent/dist/index.js ++++ b/node_modules/proxy-agent/dist/index.js +@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); + exports.ProxyAgent = exports.proxies = void 0; + const http = __importStar(require("http")); + const https = __importStar(require("https")); ++const { URL } = __importStar(require("url")); + const lru_cache_1 = __importDefault(require("lru-cache")); + const agent_base_1 = require("agent-base"); + const debug_1 = __importDefault(require("debug")); diff --git a/patches/quill+1.3.7.patch b/patches/quill+1.3.7.patch index b21d23eddb..fbd4c90c57 100644 --- a/patches/quill+1.3.7.patch +++ b/patches/quill+1.3.7.patch @@ -1,14 +1,23 @@ diff --git a/node_modules/quill/dist/quill.js b/node_modules/quill/dist/quill.js -index 811b3d0..135dfb2 100644 +index 811b3d0..9243ab6 100644 --- a/node_modules/quill/dist/quill.js +++ b/node_modules/quill/dist/quill.js +@@ -4295,7 +4295,7 @@ var Scroll = function (_Parchment$Scroll) { + value: function enable() { + var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + +- this.domNode.setAttribute('contenteditable', enabled); ++ this.domNode.setAttribute('contenteditable', enabled ? 'plaintext-only' : false); + } + }, { + key: 'formatAt', @@ -8896,7 +8896,8 @@ var debug = (0, _logger2.default)('quill:clipboard'); var DOM_KEY = '__ql-matcher'; -var CLIPBOARD_CONFIG = [[Node.TEXT_NODE, matchText], [Node.TEXT_NODE, matchNewline], ['br', matchBreak], [Node.ELEMENT_NODE, matchNewline], [Node.ELEMENT_NODE, matchBlot], [Node.ELEMENT_NODE, matchSpacing], [Node.ELEMENT_NODE, matchAttributor], [Node.ELEMENT_NODE, matchStyles], ['li', matchIndent], ['b', matchAlias.bind(matchAlias, 'bold')], ['i', matchAlias.bind(matchAlias, 'italic')], ['style', matchIgnore]]; +// var CLIPBOARD_CONFIG = [[Node.TEXT_NODE, matchText], [Node.TEXT_NODE, matchNewline], ['br', matchBreak], [Node.ELEMENT_NODE, matchNewline], [Node.ELEMENT_NODE, matchBlot], [Node.ELEMENT_NODE, matchSpacing], [Node.ELEMENT_NODE, matchAttributor], [Node.ELEMENT_NODE, matchStyles], ['li', matchIndent], ['b', matchAlias.bind(matchAlias, 'bold')], ['i', matchAlias.bind(matchAlias, 'italic')], ['style', matchIgnore]]; -+var CLIPBOARD_CONFIG = [[Node.TEXT_NODE, matchText], [Node.TEXT_NODE, matchNewline], ['br', matchBreak], [Node.ELEMENT_NODE, matchNewline], [Node.ELEMENT_NODE, matchSpacing]]; ++var CLIPBOARD_CONFIG = [[Node.TEXT_NODE, matchText], [Node.TEXT_NODE, matchNewline], ['br', matchBreak], [Node.ELEMENT_NODE, matchNewline]]; var ATTRIBUTE_ATTRIBUTORS = [_align.AlignAttribute, _direction.DirectionAttribute].reduce(function (memo, attr) { memo[attr.keyName] = attr; @@ -83,7 +92,20 @@ index 811b3d0..135dfb2 100644 } function deltaEndsWith(delta, text) { -@@ -9074,24 +9081,30 @@ function deltaEndsWith(delta, text) { +@@ -9070,28 +9077,43 @@ function deltaEndsWith(delta, text) { + } + return endText.slice(-1 * text.length) === text; + } ++function deltaIs(delta, text) { ++ var allText = ""; ++ for (var i = delta.ops.length - 1; i >= 0 && allText.length <= text.length; --i) { ++ var op = delta.ops[i]; ++ if (typeof op.insert !== 'string') break; ++ allText = op.insert + allText; ++ } ++ return allText === text; ++} + function isLine(node) { if (node.childNodes.length === 0) return false; // Exclude embed blocks var style = computeStyle(node); @@ -120,20 +142,29 @@ index 811b3d0..135dfb2 100644 }, childrenDelta); } return delta.concat(childrenDelta); -@@ -9177,8 +9190,10 @@ function matchIndent(node, delta) { +@@ -9177,8 +9199,10 @@ function matchIndent(node, delta) { } function matchNewline(node, delta) { - if (!deltaEndsWith(delta, '\n')) { - if (isLine(node) || delta.length() > 0 && node.nextSibling && isLine(node.nextSibling)) { + // if (!deltaEndsWith(delta, '\n')) { -+ if (!deltaEndsWith(delta, '\n\n')) { ++ if (!deltaIs(delta, '\n') && !deltaEndsWith(delta, '\n\n')) { + // if (isLine(node) || delta.length() > 0 && node.nextSibling && isLine(node.nextSibling)) { + if (delta.length() > 0 && isLine(node)) { delta.insert('\n'); } } -@@ -9214,7 +9229,7 @@ function matchStyles(node, delta) { +@@ -9186,7 +9210,7 @@ function matchNewline(node, delta) { + } + + function matchSpacing(node, delta) { +- if (isLine(node) && node.nextElementSibling != null && !deltaEndsWith(delta, '\n\n')) { ++ if (isLine(node) && node.nextElementSibling != null && !deltaIs(delta, '\n') && !deltaEndsWith(delta, '\n\n')) { + var nodeHeight = node.offsetHeight + parseFloat(computeStyle(node).marginTop) + parseFloat(computeStyle(node).marginBottom); + if (node.nextElementSibling.offsetTop > node.offsetTop + nodeHeight * 1.5) { + delta.insert('\n'); +@@ -9214,7 +9238,7 @@ function matchStyles(node, delta) { return delta; } @@ -142,7 +173,7 @@ index 811b3d0..135dfb2 100644 var text = node.data; // Word represents empty line with   if (node.parentNode.tagName === 'O:P') { -@@ -9238,7 +9253,7 @@ function matchText(node, delta) { +@@ -9238,7 +9262,7 @@ function matchText(node, delta) { text = text.replace(/\s+$/, replacer.bind(replacer, false)); } } diff --git a/patches/react-aria-components+1.0.0-alpha.3.patch b/patches/react-aria-components+1.0.0-alpha.3.patch new file mode 100644 index 0000000000..6c18387e1a --- /dev/null +++ b/patches/react-aria-components+1.0.0-alpha.3.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/react-aria-components/dist/types.d.ts b/node_modules/react-aria-components/dist/types.d.ts +index eb908b4..6cd530f 100644 +--- a/node_modules/react-aria-components/dist/types.d.ts ++++ b/node_modules/react-aria-components/dist/types.d.ts +@@ -44,7 +44,7 @@ interface SlotProps { + /** A slot name for the component. Slots allow the component to receive props from a parent component. */ + slot?: string; + } +-export function useContextProps(props: T & SlotProps, ref: React.ForwardedRef, context: React.Context>): [T, React.RefObject]; ++export function useContextProps(props: T & SlotProps, ref: React.ForwardedRef, context: React.Context>): [T, React.RefObject]; + interface CollectionProps extends Omit, 'children'> { + /** The contents of the collection. */ + children?: ReactNode | ((item: T) => ReactElement); diff --git a/patches/socks-proxy-agent+8.0.1.patch b/patches/socks-proxy-agent+8.0.1.patch new file mode 100644 index 0000000000..72d3bb81a4 --- /dev/null +++ b/patches/socks-proxy-agent+8.0.1.patch @@ -0,0 +1,22 @@ +diff --git a/node_modules/socks-proxy-agent/dist/index.js b/node_modules/socks-proxy-agent/dist/index.js +index 8189e01..e2dedf8 100644 +--- a/node_modules/socks-proxy-agent/dist/index.js ++++ b/node_modules/socks-proxy-agent/dist/index.js +@@ -33,6 +33,7 @@ const debug_1 = __importDefault(require("debug")); + const dns = __importStar(require("dns")); + const net = __importStar(require("net")); + const tls = __importStar(require("tls")); ++const { URL } = __importStar(require("url")); + const debug = (0, debug_1.default)('socks-proxy-agent'); + function parseSocksURL(url) { + let lookup = false; +@@ -127,6 +128,9 @@ class SocksProxyAgent extends agent_base_1.Agent { + }, + command: 'connect', + timeout: timeout ?? undefined, ++ socket_options: { ++ lookup: lookupFn, ++ }, + }; + const cleanup = (tlsSocket) => { + req.destroy(); diff --git a/protos/DeviceMessages.proto b/protos/DeviceMessages.proto index 30174af3a8..3809a47a26 100644 --- a/protos/DeviceMessages.proto +++ b/protos/DeviceMessages.proto @@ -26,6 +26,7 @@ message ProvisionMessage { optional bytes profileKey = 6; optional bool readReceipts = 7; optional uint32 ProvisioningVersion = 9; + optional bytes masterKey = 13; } enum ProvisioningVersion { diff --git a/protos/Groups.proto b/protos/Groups.proto index c2acb6dec3..1101a238b5 100644 --- a/protos/Groups.proto +++ b/protos/Groups.proto @@ -188,7 +188,7 @@ message GroupChange { } - bytes sourceUuid = 1; // Who made the change + bytes sourceUserId = 1; // Who made the change uint32 version = 2; // The change version number repeated AddMemberAction addMembers = 3; // Members added repeated DeleteMemberAction deleteMembers = 4; // Members deleted diff --git a/protos/SignalService.proto b/protos/SignalService.proto index d8382be357..5fc976738b 100644 --- a/protos/SignalService.proto +++ b/protos/SignalService.proto @@ -23,9 +23,9 @@ message Envelope { } optional Type type = 1; - optional string sourceUuid = 11; + optional string sourceServiceId = 11; optional uint32 sourceDevice = 7; - optional string destinationUuid = 13; + optional string destinationServiceId = 13; // reserved 3; // formerly optional string relay = 3; optional uint64 timestamp = 5; // reserved 6; // formerly optional bytes legacyMessage = 6; @@ -204,7 +204,7 @@ message DataMessage { optional uint64 id = 1; reserved /* author */ 2; // removed - optional string authorUuid = 5; + optional string authorAci = 5; optional string text = 3; repeated QuotedAttachment attachments = 4; repeated BodyRange bodyRanges = 6; @@ -298,7 +298,7 @@ message DataMessage { optional string emoji = 1; optional bool remove = 2; reserved /* targetAuthorE164 */ 3; // removed - optional string targetAuthorUuid = 4; + optional string targetAuthorAci = 4; optional uint64 targetTimestamp = 5; } @@ -320,7 +320,7 @@ message DataMessage { optional uint32 length = 2; oneof associatedValue { - string mentionUuid = 3; + string mentionAci = 3; Style style = 4; } } @@ -330,7 +330,7 @@ message DataMessage { } message StoryContext { - optional string authorUuid = 1; + optional string authorAci = 1; optional uint64 sentTimestamp = 2; } @@ -447,7 +447,7 @@ message Verified { } optional string destination = 1; - optional string destinationUuid = 5; + optional string destinationAci = 5; optional bytes identityKey = 2; optional State state = 3; optional bytes nullMessage = 4; @@ -457,27 +457,18 @@ message SyncMessage { message Sent { message UnidentifiedDeliveryStatus { optional string destination = 1; - oneof destinationServiceId { - string destinationAci = 3; - string destinationPni = 4; - } + optional string destinationServiceId = 3; optional bool unidentified = 2; } message StoryMessageRecipient { - oneof destinationServiceId { - string destinationAci = 1; - string destinationPni = 4; - } + optional string destinationServiceId = 1; repeated string distributionListIds = 2; optional bool isAllowedToReply = 3; } optional string destination = 1; - oneof destinationServiceId { - string destinationAci = 7; - string destinationPni = 11; - } + optional string destinationServiceId = 7; optional uint64 timestamp = 2; optional DataMessage message = 3; optional uint64 expirationStartTimestamp = 4; @@ -495,7 +486,7 @@ message SyncMessage { message Blocked { repeated string numbers = 1; - repeated string uuids = 3; + repeated string acis = 3; repeated bytes groupIds = 2; } @@ -514,18 +505,19 @@ message SyncMessage { } message Keys { - optional bytes storageService = 1; + optional bytes storageService = 1; // deprecated: this field will be removed in a future release. + optional bytes master = 2; } message Read { optional string sender = 1; - optional string senderUuid = 3; + optional string senderAci = 3; optional uint64 timestamp = 2; } message Viewed { optional string senderE164 = 1; - optional string senderUuid = 3; + optional string senderAci = 3; optional uint64 timestamp = 2; } @@ -551,7 +543,7 @@ message SyncMessage { message ViewOnceOpen { optional string sender = 1; - optional string senderUuid = 3; + optional string senderAci = 3; optional uint64 timestamp = 2; } @@ -565,7 +557,7 @@ message SyncMessage { } optional string threadE164 = 1; - optional string threadUuid = 2; + optional string threadAci = 2; optional bytes groupId = 3; optional Type type = 4; } @@ -592,9 +584,11 @@ message SyncMessage { message CallEvent { enum Type { - UNKNOWN = 0; - AUDIO_CALL = 1; - VIDEO_CALL = 2; + UNKNOWN = 0; + AUDIO_CALL = 1; + VIDEO_CALL = 2; + GROUP_CALL = 3; + AD_HOC_CALL = 4; } enum Direction { @@ -607,9 +601,10 @@ message SyncMessage { UNKNOWN = 0; ACCEPTED = 1; NOT_ACCEPTED = 2; + DELETE = 3; } - optional bytes peerUuid = 1; + optional bytes peerId = 1; optional uint64 callId = 2; optional uint64 timestamp = 3; optional Type type = 4; @@ -617,6 +612,15 @@ message SyncMessage { optional Event event = 6; } + message CallLogEvent { + enum Type { + CLEAR = 0; + } + + optional Type type = 1; + optional uint64 timestamp = 2; + } + optional Sent sent = 1; optional Contacts contacts = 2; reserved /* groups */ 3; @@ -636,6 +640,8 @@ message SyncMessage { reserved 17; // pniIdentity optional PniChangeNumber pniChangeNumber = 18; optional CallEvent callEvent = 19; + reserved 20; // callLinkUpdate + optional CallLogEvent callLogEvent = 21; } message AttachmentPointer { @@ -680,13 +686,13 @@ message ContactDetails { } optional string number = 1; - optional string uuid = 9; + optional string aci = 9; optional string name = 2; optional Avatar avatar = 3; - optional string color = 4; - optional Verified verified = 5; - optional bytes profileKey = 6; - optional bool blocked = 7; + // reserved 4; // formerly color + // reserved 5; // formerly verified + // reserved 6; // formerly profileKey + // reserved 7; // formerly blocked optional uint32 expireTimer = 8; optional uint32 inboxPosition = 10; } diff --git a/protos/SignalStorage.proto b/protos/SignalStorage.proto index e96e2cd8ba..d130a181dc 100644 --- a/protos/SignalStorage.proto +++ b/protos/SignalStorage.proto @@ -77,7 +77,7 @@ message ContactRecord { UNVERIFIED = 2; } - optional string serviceUuid = 1; + optional string aci = 1; optional string serviceE164 = 2; optional string pni = 15; optional bytes profileKey = 3; @@ -136,7 +136,7 @@ message AccountRecord { message PinnedConversation { message Contact { - optional string uuid = 1; + optional string serviceId = 1; optional string e164 = 2; } @@ -203,7 +203,7 @@ message AccountRecord { message StoryDistributionListRecord { optional bytes identifier = 1; optional string name = 2; - repeated string recipientUuids = 3; + repeated string recipientServiceIds = 3; optional uint64 deletedAtTimestamp = 4; optional bool allowsReplies = 5; optional bool isBlockList = 6; diff --git a/sticker-creator/package.json b/sticker-creator/package.json index ae5810552b..260109de6a 100644 --- a/sticker-creator/package.json +++ b/sticker-creator/package.json @@ -25,6 +25,7 @@ "@formatjs/fast-memoize": "1.2.8", "@indutny/emoji-picker-react": "4.4.9", "@popperjs/core": "2.11.7", + "@react-aria/interactions": "3.19.0", "@reduxjs/toolkit": "1.9.5", "@stablelib/x25519": "1.0.3", "base64-js": "1.5.1", diff --git a/sticker-creator/src/colors.scss b/sticker-creator/src/colors.scss index fc3ca03a03..96733f9591 100644 --- a/sticker-creator/src/colors.scss +++ b/sticker-creator/src/colors.scss @@ -18,6 +18,7 @@ $color-gray-60: #5e5e5e; $color-gray-62: #545454; $color-gray-65: #4a4a4a; $color-gray-75: #3b3b3b; +$color-gray-78: #343434; $color-gray-80: #2e2e2e; $color-gray-90: #1b1b1b; $color-gray-95: #121212; @@ -26,6 +27,7 @@ $color-black: #000000; $color-white-alpha-06: rgba($color-white, 0.06); $color-white-alpha-08: rgba($color-white, 0.08); $color-white-alpha-12: rgba($color-white, 0.12); +$color-white-alpha-16: rgba($color-white, 0.16); $color-white-alpha-20: rgba($color-white, 0.2); $color-white-alpha-40: rgba($color-white, 0.4); $color-white-alpha-60: rgba($color-white, 0.6); diff --git a/sticker-creator/src/components/ArtFrame.tsx b/sticker-creator/src/components/ArtFrame.tsx index bd2393f660..e3bc2e1f56 100644 --- a/sticker-creator/src/components/ArtFrame.tsx +++ b/sticker-creator/src/components/ArtFrame.tsx @@ -1,7 +1,7 @@ // Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React from 'react'; +import React, { useRef } from 'react'; import { createPortal } from 'react-dom'; import classNames from 'classnames'; import { @@ -11,6 +11,7 @@ import { } from 'react-popper'; import type { EmojiClickData } from '@indutny/emoji-picker-react'; +import { useInteractOutside } from '@react-aria/interactions'; import { AddEmoji } from '../elements/icons'; import type { Props as DropZoneProps } from '../elements/DropZone'; import { DropZone } from '../elements/DropZone'; @@ -19,11 +20,9 @@ import { Spinner } from '../elements/Spinner'; import styles from './ArtFrame.module.scss'; import { useI18n } from '../contexts/I18n'; import { assert } from '../util/assert'; -import { noop } from '../util/noop'; import { ArtType } from '../constants'; import type { EmojiData } from '../types.d'; import EMOJI_SHEET from '../assets/emoji.webp'; -import { PopperRootContext } from './PopperRootContext'; import EmojiPicker from './EmojiPicker'; export type Mode = 'removable' | 'pick-emoji' | 'add'; @@ -71,11 +70,9 @@ export const ArtFrame = React.memo(function ArtFrame({ }: Props) { const i18n = useI18n(); const [emojiPickerOpen, setEmojiPickerOpen] = React.useState(false); - const [emojiPopperRoot, setEmojiPopperRoot] = - React.useState(null); + const emojiPickerPopperRef = useRef(null); const [previewActive, setPreviewActive] = React.useState(false); - const [previewPopperRoot, setPreviewPopperRoot] = - React.useState(null); + const previewPopperRef = useRef(null); const timerRef = React.useRef(); const handleToggleEmojiPicker = React.useCallback(() => { @@ -138,51 +135,19 @@ export const ArtFrame = React.memo(function ArtFrame({ [timerRef] ); - const { createRoot, removeRoot } = React.useContext(PopperRootContext); + useInteractOutside({ + ref: emojiPickerPopperRef, + onInteractOutside() { + setEmojiPickerOpen(false); + }, + }); - // Create popper root and handle outside clicks - React.useEffect(() => { - if (emojiPickerOpen) { - const root = createRoot(); - setEmojiPopperRoot(root); - const handleOutsideClick = ({ target }: MouseEvent) => { - const targetNode = target as HTMLElement; - const button = targetNode.closest(`button.${styles.emojiButton}`); - if (!root.contains(targetNode) && !button) { - setEmojiPickerOpen(false); - } - }; - document.addEventListener('click', handleOutsideClick); - - return () => { - removeRoot(root); - setEmojiPopperRoot(null); - document.removeEventListener('click', handleOutsideClick); - }; - } - - return noop; - }, [createRoot, emojiPickerOpen, removeRoot]); - - React.useEffect(() => { - if (mode !== 'pick-emoji' && image && previewActive) { - const root = createRoot(); - setPreviewPopperRoot(root); - - return () => { - removeRoot(root); - }; - } - - return noop; - }, [ - createRoot, - image, - mode, - previewActive, - removeRoot, - setPreviewPopperRoot, - ]); + useInteractOutside({ + ref: previewPopperRef, + onInteractOutside() { + setPreviewActive(false); + }, + }); const [dragActive, setDragActive] = React.useState(false); @@ -246,23 +211,27 @@ export const ArtFrame = React.memo(function ArtFrame({ )} - {emojiPickerOpen && emojiPopperRoot + {emojiPickerOpen ? createPortal( - + {({ ref, style }) => (

)} , - emojiPopperRoot + document.body ) : null} ) : null} - {mode !== 'pick-emoji' && image && previewActive && previewPopperRoot + {mode !== 'pick-emoji' && image && previewActive ? createPortal( , - previewPopperRoot + document.body ) : null} diff --git a/sticker-creator/src/components/ConfirmModal.tsx b/sticker-creator/src/components/ConfirmModal.tsx index 6348aed2d0..3aedc85116 100644 --- a/sticker-creator/src/components/ConfirmModal.tsx +++ b/sticker-creator/src/components/ConfirmModal.tsx @@ -1,45 +1,23 @@ // Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React from 'react'; +import React, { useRef } from 'react'; import { createPortal } from 'react-dom'; +import { useInteractOutside } from '@react-aria/interactions'; import styles from './ConfirmModal.module.scss'; import type { Props } from '../elements/ConfirmDialog'; import { ConfirmDialog } from '../elements/ConfirmDialog'; export type Mode = 'removable' | 'pick-emoji' | 'add'; -export const ConfirmModal = React.memo(function ConfirmModalInner( - props: Props & { buttonRef: React.RefObject } -) { - const { buttonRef, onCancel } = props; - const [popperRoot, setPopperRoot] = React.useState(); - - // Create popper root and handle outside clicks - React.useEffect(() => { - const root = document.createElement('div'); - setPopperRoot(root); - document.body.appendChild(root); - const handleOutsideClick = ({ target }: MouseEvent) => { - const node = target as Node; - if (!root.contains(node) && !buttonRef.current?.contains(node)) { - onCancel(); - } - }; - document.addEventListener('click', handleOutsideClick); - - return () => { - document.body.removeChild(root); - document.removeEventListener('click', handleOutsideClick); - }; - }, [onCancel, buttonRef]); - - return popperRoot - ? createPortal( -
- -
, - popperRoot - ) - : null; -}); +export function ConfirmModal(props: Props): JSX.Element { + const { onCancel } = props; + const ref = useRef(null); + useInteractOutside({ ref, onInteractOutside: onCancel }); + return createPortal( +
+ +
, + document.body + ); +} diff --git a/sticker-creator/src/components/PopperRootContext.tsx b/sticker-creator/src/components/PopperRootContext.tsx deleted file mode 100644 index aa43a32465..0000000000 --- a/sticker-creator/src/components/PopperRootContext.tsx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React from 'react'; - -const makeApi = (classes?: Array) => ({ - createRoot: () => { - const div = document.createElement('div'); - - if (classes) { - classes.forEach(theme => { - div.classList.add(theme); - }); - } - - document.body.appendChild(div); - - return div; - }, - removeRoot: (root: HTMLElement) => { - document.body.removeChild(root); - }, -}); - -export const PopperRootContext = React.createContext(makeApi()); - -export type ClassyProviderProps = { - classes?: Array; - children?: React.ReactNode; -}; - -export function ClassyProvider({ - classes, - children, -}: ClassyProviderProps): JSX.Element { - const api = React.useMemo(() => makeApi(classes), [classes]); - - return ( - - {children} - - ); -} diff --git a/sticker-creator/src/elements/Button.tsx b/sticker-creator/src/elements/Button.tsx index b025e509fd..dbaa829457 100644 --- a/sticker-creator/src/elements/Button.tsx +++ b/sticker-creator/src/elements/Button.tsx @@ -31,7 +31,6 @@ const getClassName = ({ primary, pill }: Props) => { export function Button({ className, children, - buttonRef, primary, ...otherProps }: React.PropsWithChildren): JSX.Element { @@ -42,7 +41,6 @@ export function Button({ getClassName({ primary, ...otherProps }), className )} - ref={buttonRef} {...otherProps} > {children} diff --git a/sticker-creator/src/elements/ConfirmDialog.tsx b/sticker-creator/src/elements/ConfirmDialog.tsx index 63746d04e3..2a7c0d8976 100644 --- a/sticker-creator/src/elements/ConfirmDialog.tsx +++ b/sticker-creator/src/elements/ConfirmDialog.tsx @@ -1,7 +1,8 @@ // Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React from 'react'; +import type { Ref } from 'react'; +import React, { forwardRef } from 'react'; import { useI18n } from '../contexts/I18n'; import styles from './ConfirmDialog.module.scss'; @@ -16,19 +17,15 @@ export type Props = Readonly<{ onCancel: () => unknown; }>; -export function ConfirmDialog({ - title, - children, - confirm, - cancel, - onConfirm, - onCancel, -}: Props): JSX.Element { +export const ConfirmDialog = forwardRef(function ConfirmDialog( + { title, children, confirm, cancel, onConfirm, onCancel }: Props, + ref: Ref +): JSX.Element { const i18n = useI18n(); const cancelText = cancel || i18n('StickerCreator--ConfirmDialog--cancel'); return ( -
+

{title}

{children}

@@ -40,4 +37,4 @@ export function ConfirmDialog({
); -} +}); diff --git a/sticker-creator/src/fonts.scss b/sticker-creator/src/fonts.scss index 08eb87069b..23758b7955 100644 --- a/sticker-creator/src/fonts.scss +++ b/sticker-creator/src/fonts.scss @@ -8,9 +8,9 @@ $inter: Inter, 'Helvetica Neue', 'Source Sans Pro', 'Source Han Sans SC', @mixin font-family { font-family: $inter; &:lang(ja) { - font-family: 'SF Pro JP', 'Hiragino Kaku Gothic Pro', 'ăƒ’ăƒ©ă‚źăƒŽè§’ă‚Ž Pro W3', - ăƒĄă‚€ăƒȘă‚Ș, Meiryo, 'ïŒ­ïŒł ïŒ°ă‚Žă‚·ăƒƒă‚Ż', 'Helvetica Neue', Helvetica, Arial, - sans-serif; + font-family: Inter, 'SF Pro', 'SF Pro JP', 'BIZ UDGothic', + 'Hiragino Kaku Gothic Pro', 'ăƒ’ăƒ©ă‚źăƒŽè§’ă‚Ž Pro W3', ăƒĄă‚€ăƒȘă‚Ș, Meiryo, + 'ïŒ­ïŒł ïŒ°ă‚Žă‚·ăƒƒă‚Ż', 'Helvetica Neue', Helvetica, Arial, sans-serif; } } diff --git a/sticker-creator/src/routes/art/AppStage.module.scss b/sticker-creator/src/routes/art/AppStage.module.scss index 80970be7b8..bfc092d622 100644 --- a/sticker-creator/src/routes/art/AppStage.module.scss +++ b/sticker-creator/src/routes/art/AppStage.module.scss @@ -81,6 +81,6 @@ } &:dir(rtl) { // stylelint-disable-next-line declaration-property-value-disallowed-list - transform: translate(50%, 0px) + transform: translate(50%, 0px); } } diff --git a/sticker-creator/src/routes/art/AppStage.tsx b/sticker-creator/src/routes/art/AppStage.tsx index 4ac72d31e3..3d6372bee8 100644 --- a/sticker-creator/src/routes/art/AppStage.tsx +++ b/sticker-creator/src/routes/art/AppStage.tsx @@ -24,7 +24,6 @@ export type Props = Readonly<{ noScroll?: boolean; onNext?: () => unknown; onPrev?: () => unknown; - nextButtonRef?: React.RefObject; nextText?: string; showGuide?: boolean; setShowGuide?: (value: boolean) => unknown; @@ -48,7 +47,6 @@ export function AppStage(props: Props): JSX.Element { next, nextActive, nextText, - nextButtonRef, noScroll, onNext, onPrev, @@ -99,7 +97,6 @@ export function AppStage(props: Props): JSX.Element { ) : null} {next || onNext ? ( - } - > - { - setMessageText(updatedMessageText); - setBodyRanges(updatedBodyRanges); - }} - scrollerRef={scrollerRef} - draftText={draftText} - bodyRanges={draftBodyRanges} - onSubmit={noop} - onScroll={updateScrollState} - theme={theme} - /> - - ); -} diff --git a/ts/components/AddGroupMemberErrorDialog.stories.tsx b/ts/components/AddGroupMemberErrorDialog.stories.tsx index 9ced0f47f7..5db6945b6c 100644 --- a/ts/components/AddGroupMemberErrorDialog.stories.tsx +++ b/ts/components/AddGroupMemberErrorDialog.stories.tsx @@ -5,8 +5,10 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; +import type { PropsType } from './AddGroupMemberErrorDialog'; import { AddGroupMemberErrorDialog, AddGroupMemberErrorDialogMode, @@ -16,24 +18,22 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/AddGroupMemberErrorDialog', -}; +} satisfies Meta; const defaultProps = { i18n, onClose: action('onClose'), }; -export const _MaximumGroupSize = (): JSX.Element => ( - -); - -_MaximumGroupSize.story = { - name: 'Maximum group size', -}; +export function MaximumGroupSize(): JSX.Element { + return ( + + ); +} export function MaximumRecommendedGroupSize(): JSX.Element { return ( @@ -44,7 +44,3 @@ export function MaximumRecommendedGroupSize(): JSX.Element { /> ); } - -MaximumRecommendedGroupSize.story = { - name: 'Maximum recommended group size', -}; diff --git a/ts/components/AddGroupMemberErrorDialog.tsx b/ts/components/AddGroupMemberErrorDialog.tsx index cae318cfa2..7cb81962dc 100644 --- a/ts/components/AddGroupMemberErrorDialog.tsx +++ b/ts/components/AddGroupMemberErrorDialog.tsx @@ -23,7 +23,7 @@ type PropsDataType = recommendedMaximumNumberOfContacts: number; }; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => void; } & PropsDataType; diff --git a/ts/components/AddUserToAnotherGroupModal.stories.tsx b/ts/components/AddUserToAnotherGroupModal.stories.tsx index 4848542fa9..b3ffe7e607 100644 --- a/ts/components/AddUserToAnotherGroupModal.stories.tsx +++ b/ts/components/AddUserToAnotherGroupModal.stories.tsx @@ -1,8 +1,9 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React from 'react'; -import type { Meta, Story } from '@storybook/react'; +import React, { useContext } from 'react'; +import type { Meta, StoryFn } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; import type { Props } from './AddUserToAnotherGroupModal'; import enMessages from '../../_locales/en/messages.json'; @@ -19,28 +20,25 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/AddUserToAnotherGroupModal', component: AddUserToAnotherGroupModal, - argTypes: { - candidateConversations: { - defaultValue: Array.from(Array(100), () => getDefaultGroup()), - }, - contact: { - defaultValue: getDefaultConversation(), - }, - i18n: { - defaultValue: i18n, - }, - addMembersToGroup: { action: true }, - toggleAddUserToAnotherGroupModal: { action: true }, + args: { + i18n, + candidateConversations: Array.from(Array(100), () => getDefaultGroup()), + contact: getDefaultConversation(), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ( - -); +const Template: StoryFn = args => { + return ( + + ); +}; export const Modal = Template.bind({}); -Modal.args = {}; diff --git a/ts/components/AddUserToAnotherGroupModal.tsx b/ts/components/AddUserToAnotherGroupModal.tsx index 4468bf5787..bc929b133d 100644 --- a/ts/components/AddUserToAnotherGroupModal.tsx +++ b/ts/components/AddUserToAnotherGroupModal.tsx @@ -26,7 +26,7 @@ import { SizeObserver } from '../hooks/useSizeObserver'; type OwnProps = { i18n: LocalizerType; theme: ThemeType; - contact: Pick; + contact: Pick; candidateConversations: ReadonlyArray; regionCode: string | undefined; }; @@ -119,11 +119,12 @@ export function AddUserToAnotherGroupModal({ let disabledReason; - if (memberships.some(c => c.uuid === contact.uuid)) { + if (memberships.some(c => c.aci === contact.serviceId)) { disabledReason = DisabledReason.AlreadyMember; } else if ( - pendingApprovalMemberships.some(c => c.uuid === contact.uuid) || - pendingMemberships.some(c => c.uuid === contact.uuid) + pendingApprovalMemberships.some(c => c.aci === contact.serviceId) || + pendingMemberships.some(c => c.serviceId === contact.serviceId) || + pendingMemberships.some(c => c.serviceId === contact.pni) ) { disabledReason = DisabledReason.Pending; } diff --git a/ts/components/Alert.stories.tsx b/ts/components/Alert.stories.tsx index d590dcef9f..272b6af0d4 100644 --- a/ts/components/Alert.stories.tsx +++ b/ts/components/Alert.stories.tsx @@ -2,18 +2,18 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; +import type { PropsType } from './Alert'; import { Alert } from './Alert'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Alert', -}; +} satisfies Meta; const defaultProps = { i18n, @@ -33,10 +33,6 @@ export function TitleAndBodyAreStrings(): JSX.Element { ); } -TitleAndBodyAreStrings.story = { - name: 'Title and body are strings', -}; - export function BodyIsAReactNode(): JSX.Element { return ( ); } - -LongBodyWithTitle.story = { - name: 'Long body (with title)', -}; diff --git a/ts/components/Alert.tsx b/ts/components/Alert.tsx index c9ac714b7d..56eec431d7 100644 --- a/ts/components/Alert.tsx +++ b/ts/components/Alert.tsx @@ -9,7 +9,7 @@ import type { Theme } from '../util/theme'; import { Button } from './Button'; import { Modal } from './Modal'; -type PropsType = { +export type PropsType = { body: ReactNode; i18n: LocalizerType; onClose: () => void; diff --git a/ts/components/AnimatedEmojiGalore.stories.tsx b/ts/components/AnimatedEmojiGalore.stories.tsx index 491e2eec03..acc4edc314 100644 --- a/ts/components/AnimatedEmojiGalore.stories.tsx +++ b/ts/components/AnimatedEmojiGalore.stories.tsx @@ -4,12 +4,13 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './AnimatedEmojiGalore'; import { AnimatedEmojiGalore } from './AnimatedEmojiGalore'; export default { title: 'Components/AnimatedEmojiGalore', -}; +} satisfies Meta; function getDefaultProps(): PropsType { return { diff --git a/ts/components/App.tsx b/ts/components/App.tsx index a350b76c84..5343f060e2 100644 --- a/ts/components/App.tsx +++ b/ts/components/App.tsx @@ -10,6 +10,7 @@ import type { MenuOptionsType, MenuActionType } from '../types/menu'; import type { AnyToast } from '../types/Toast'; import type { ViewStoryActionCreatorType } from '../state/ducks/stories'; import type { LocalizerType } from '../types/Util'; +import type { VerificationTransport } from '../types/VerificationTransport'; import { ThemeType } from '../types/Util'; import { AppViewType } from '../state/ducks/app'; import { SmartInstallScreen } from '../state/smart/InstallScreen'; @@ -22,20 +23,22 @@ import { useReducedMotion } from '../hooks/useReducedMotion'; type PropsType = { appView: AppViewType; openInbox: () => void; - registerSingleDevice: (number: string, code: string) => Promise; + registerSingleDevice: ( + number: string, + code: string, + sessionId: string + ) => Promise; renderCallManager: () => JSX.Element; renderGlobalModalContainer: () => JSX.Element; - isShowingStoriesView: boolean; i18n: LocalizerType; - renderStories: (closeView: () => unknown) => JSX.Element; hasSelectedStoryData: boolean; renderStoryViewer: (closeView: () => unknown) => JSX.Element; renderLightbox: () => JSX.Element | null; requestVerification: ( - type: 'sms' | 'voice', number: string, - token: string - ) => Promise; + captcha: string, + transport: VerificationTransport + ) => Promise<{ sessionId: string }>; theme: ThemeType; isMaximized: boolean; isFullScreen: boolean; @@ -53,7 +56,6 @@ type PropsType = { titleBarDoubleClick: () => void; toast?: AnyToast; scrollToMessage: (conversationId: string, messageId: string) => unknown; - toggleStoriesView: () => unknown; viewStory: ViewStoryActionCreatorType; renderInbox: () => JSX.Element; }; @@ -69,7 +71,6 @@ export function App({ i18n, isFullScreen, isMaximized, - isShowingStoriesView, menuOptions, onUndoArchive, openFileInFolder, @@ -81,13 +82,11 @@ export function App({ renderGlobalModalContainer, renderInbox, renderLightbox, - renderStories, renderStoryViewer, requestVerification, theme, titleBarDoubleClick, toast, - toggleStoriesView, viewStory, }: PropsType): JSX.Element { let contents; @@ -183,7 +182,6 @@ export function App({ {renderGlobalModalContainer()} {renderCallManager()} {renderLightbox()} - {isShowingStoriesView && renderStories(toggleStoriesView)} {hasSelectedStoryData && renderStoryViewer(() => viewStory({ closeViewer: true }))}
diff --git a/ts/components/Avatar.stories.tsx b/ts/components/Avatar.stories.tsx index ec29c5cad1..d09181694d 100644 --- a/ts/components/Avatar.stories.tsx +++ b/ts/components/Avatar.stories.tsx @@ -1,13 +1,12 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import * as React from 'react'; import { action } from '@storybook/addon-actions'; -import { expect } from '@storybook/jest'; +import { expect, jest } from '@storybook/jest'; import { isBoolean } from 'lodash'; import { within, userEvent } from '@storybook/testing-library'; - import type { AvatarColorType } from '../types/Colors'; import type { Props } from './Avatar'; import enMessages from '../../_locales/en/messages.json'; @@ -42,7 +41,6 @@ export default { }, blur: { control: { type: 'radio' }, - defaultValue: undefined, options: { Undefined: undefined, NoBlur: AvatarBlur.NoBlur, @@ -51,14 +49,12 @@ export default { }, }, color: { - defaultValue: AvatarColors[0], options: colorMap, }, conversationType: { control: { type: 'radio' }, options: conversationTypeMap, }, - onClick: { action: true }, size: { control: false, }, @@ -68,11 +64,16 @@ export default { }, theme: { control: { type: 'radio' }, - defaultValue: ThemeType.light, options: ThemeType, }, }, -} as Meta; + args: { + blur: undefined, + color: AvatarColors[0], + onClick: action('onClick'), + theme: ThemeType.light, + }, +} satisfies Meta; const createProps = (overrideProps: Partial = {}): Props => ({ acceptedMessageRequest: isBoolean(overrideProps.acceptedMessageRequest) @@ -87,7 +88,7 @@ const createProps = (overrideProps: Partial = {}): Props => ({ isMe: false, loading: Boolean(overrideProps.loading), noteToSelf: Boolean(overrideProps.noteToSelf), - onClick: action('onClick'), + onClick: jest.fn(action('onClick')), onClickBadge: action('onClickBadge'), phoneNumber: overrideProps.phoneNumber || '', searchResult: Boolean(overrideProps.searchResult), @@ -103,16 +104,18 @@ const sizes = Object.values(AvatarSize).filter( ) as Array; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ( - <> - {sizes.map(size => ( - - ))} - -); +const Template: StoryFn = (args: Props) => { + return ( + <> + {sizes.map(size => ( + + ))} + + ); +}; // eslint-disable-next-line react/function-component-definition -const TemplateSingle: Story = args => ( +const TemplateSingle: StoryFn = (args: Props) => ( ); @@ -120,72 +123,50 @@ export const Default = Template.bind({}); Default.args = createProps({ avatarPath: '/fixtures/giphy-GVNvOUpeYmI7e.gif', }); -Default.play = async ({ args, canvasElement }) => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +Default.play = async (context: any) => { + const { args, canvasElement } = context; const canvas = within(canvasElement); const [avatar] = canvas.getAllByRole('button'); await userEvent.click(avatar); await expect(args.onClick).toHaveBeenCalled(); }; -Default.story = { - name: 'Avatar', -}; export const WithBadge = Template.bind({}); WithBadge.args = createProps({ avatarPath: '/fixtures/kitten-3-64-64.jpg', badge: getFakeBadge(), }); -WithBadge.story = { - name: 'With badge', -}; export const WideImage = Template.bind({}); WideImage.args = createProps({ avatarPath: '/fixtures/wide.jpg', }); -WideImage.story = { - name: 'Wide image', -}; export const OneWordName = Template.bind({}); OneWordName.args = createProps({ title: 'John', }); -OneWordName.story = { - name: 'One-word Name', -}; export const TwoWordName = Template.bind({}); TwoWordName.args = createProps({ title: 'John Smith', }); -TwoWordName.story = { - name: 'Two-word Name', -}; export const WideInitials = Template.bind({}); WideInitials.args = createProps({ title: 'Walter White', }); -WideInitials.story = { - name: 'Wide initials', -}; export const ThreeWordName = Template.bind({}); ThreeWordName.args = createProps({ title: 'Walter H. White', }); -ThreeWordName.story = { - name: 'Three-word name', -}; export const NoteToSelf = Template.bind({}); NoteToSelf.args = createProps({ noteToSelf: true, }); -NoteToSelf.story = { - name: 'Note to Self', -}; export const ContactIcon = Template.bind({}); ContactIcon.args = createProps(); @@ -227,9 +208,6 @@ BrokenAvatarForGroup.args = createProps({ avatarPath: 'badimage.png', conversationType: 'group', }); -BrokenAvatarForGroup.story = { - name: 'Broken Avatar for Group', -}; export const Loading = Template.bind({}); Loading.args = createProps({ @@ -242,42 +220,26 @@ BlurredBasedOnProps.args = createProps({ avatarPath: '/fixtures/kitten-3-64-64.jpg', }); -BlurredBasedOnProps.story = { - name: 'Blurred based on props', -}; - export const ForceBlurred = TemplateSingle.bind({}); ForceBlurred.args = createProps({ avatarPath: '/fixtures/kitten-3-64-64.jpg', blur: AvatarBlur.BlurPicture, }); -ForceBlurred.story = { - name: 'Force-blurred', -}; export const BlurredWithClickToView = TemplateSingle.bind({}); BlurredWithClickToView.args = createProps({ avatarPath: '/fixtures/kitten-3-64-64.jpg', blur: AvatarBlur.BlurPictureWithClickToView, }); -BlurredWithClickToView.story = { - name: 'Blurred with "click to view"', -}; export const StoryUnread = TemplateSingle.bind({}); StoryUnread.args = createProps({ avatarPath: '/fixtures/kitten-3-64-64.jpg', storyRing: HasStories.Unread, }); -StoryUnread.story = { - name: 'Story: unread', -}; export const StoryRead = TemplateSingle.bind({}); StoryRead.args = createProps({ avatarPath: '/fixtures/kitten-3-64-64.jpg', storyRing: HasStories.Read, }); -StoryRead.story = { - name: 'Story: read', -}; diff --git a/ts/components/Avatar.tsx b/ts/components/Avatar.tsx index e3db4cacb3..d376c15fb5 100644 --- a/ts/components/Avatar.tsx +++ b/ts/components/Avatar.tsx @@ -12,6 +12,7 @@ import React, { useEffect, useState } from 'react'; import classNames from 'classnames'; import { noop } from 'lodash'; +import { filterDOMProps } from '@react-aria/utils'; import type { AvatarColorType } from '../types/Colors'; import type { BadgeType } from '../badges/types'; import type { LocalizerType } from '../types/Util'; @@ -37,9 +38,12 @@ export enum AvatarSize { TWENTY = 20, TWENTY_EIGHT = 28, THIRTY_TWO = 32, + THIRTY_SIX = 36, + FORTY = 40, FORTY_EIGHT = 48, FIFTY_TWO = 52, EIGHTY = 80, + NINETY_SIX = 96, } type BadgePlacementType = { bottom: number; right: number }; @@ -239,7 +243,7 @@ export function Avatar({ if (onClick) { contents = ( -
- - - {hasPendingUpdate && ( - - )} - - ); -} diff --git a/ts/components/AvatarPreview.stories.tsx b/ts/components/AvatarPreview.stories.tsx index 3868ef0c40..bedde737a8 100644 --- a/ts/components/AvatarPreview.stories.tsx +++ b/ts/components/AvatarPreview.stories.tsx @@ -6,6 +6,7 @@ import { chunk } from 'lodash'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './AvatarPreview'; import { AvatarPreview } from './AvatarPreview'; import { AvatarColors } from '../types/Colors'; @@ -37,7 +38,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/AvatarPreview', -}; +} satisfies Meta; export function NoStatePersonal(): JSX.Element { return ( @@ -50,10 +51,6 @@ export function NoStatePersonal(): JSX.Element { ); } -NoStatePersonal.story = { - name: 'No state (personal)', -}; - export function NoStateGroup(): JSX.Element { return ( ; } -Value.story = { - name: 'value', -}; - export function Path(): JSX.Element { return ( ); } - -Style.story = { - name: 'style', -}; diff --git a/ts/components/AvatarTextEditor.stories.tsx b/ts/components/AvatarTextEditor.stories.tsx index 3d113be248..8058bb7764 100644 --- a/ts/components/AvatarTextEditor.stories.tsx +++ b/ts/components/AvatarTextEditor.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -22,7 +23,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/AvatarTextEditor', -}; +} satisfies Meta; export function Empty(): JSX.Element { return ; @@ -42,10 +43,6 @@ export function WithData(): JSX.Element { ); } -WithData.story = { - name: 'with Data', -}; - export function WithWideCharacters(): JSX.Element { return ( ); } - -WithWideCharacters.story = { - name: 'with wide characters', -}; diff --git a/ts/components/AvatarUploadButton.stories.tsx b/ts/components/AvatarUploadButton.stories.tsx index 1f4aed996b..6a866de048 100644 --- a/ts/components/AvatarUploadButton.stories.tsx +++ b/ts/components/AvatarUploadButton.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -20,7 +21,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/AvatarUploadButton', -}; +} satisfies Meta; export function Default(): JSX.Element { return ; diff --git a/ts/components/BadgeDescription.stories.tsx b/ts/components/BadgeDescription.stories.tsx index 5edb8e2d51..fe9b1a8f14 100644 --- a/ts/components/BadgeDescription.stories.tsx +++ b/ts/components/BadgeDescription.stories.tsx @@ -3,11 +3,13 @@ import React from 'react'; +import type { Meta } from '@storybook/react'; +import type { Props } from './BadgeDescription'; import { BadgeDescription } from './BadgeDescription'; export default { title: 'Components/BadgeDescription', -}; +} satisfies Meta; export function NormalName(): JSX.Element { return ( @@ -19,11 +21,7 @@ export function NormalName(): JSX.Element { ); } -NormalName.story = { - name: 'Normal name', -}; - -export function NameWithRtlOverrides(): JSX.Element { +export function NameWithRTLOverrides(): JSX.Element { return ( ); } - -NameWithRtlOverrides.story = { - name: 'Name with RTL overrides', -}; diff --git a/ts/components/BadgeDescription.tsx b/ts/components/BadgeDescription.tsx index e5343fa927..5fee7f4a02 100644 --- a/ts/components/BadgeDescription.tsx +++ b/ts/components/BadgeDescription.tsx @@ -5,15 +5,17 @@ import type { ReactChild, ReactElement } from 'react'; import React from 'react'; import { ContactName } from './conversation/ContactName'; +export type Props = Readonly<{ + firstName?: string; + template: string; + title: string; +}>; + export function BadgeDescription({ firstName, template, title, -}: Readonly<{ - firstName?: string; - template: string; - title: string; -}>): ReactElement { +}: Props): ReactElement { const result: Array = []; let lastIndex = 0; diff --git a/ts/components/BadgeDialog.stories.tsx b/ts/components/BadgeDialog.stories.tsx index 36ff3b2dcc..c45deeea0b 100644 --- a/ts/components/BadgeDialog.stories.tsx +++ b/ts/components/BadgeDialog.stories.tsx @@ -5,18 +5,20 @@ import type { ComponentProps } from 'react'; import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; import { getFakeBadge, getFakeBadges } from '../test-both/helpers/getFakeBadge'; import { repeat, zipObject } from '../util/iterables'; import { BadgeImageTheme } from '../badges/BadgeImageTheme'; +import type { PropsType } from './BadgeDialog'; import { BadgeDialog } from './BadgeDialog'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/BadgeDialog', -}; +} satisfies Meta; const defaultProps: ComponentProps = { areWeASubscriber: false, @@ -31,18 +33,10 @@ export function NoBadgesClosedImmediately(): JSX.Element { return ; } -NoBadgesClosedImmediately.story = { - name: 'No badges (closed immediately)', -}; - export function OneBadge(): JSX.Element { return ; } -OneBadge.story = { - name: 'One badge', -}; - export function BadgeWithNoImageShouldBeImpossible(): JSX.Element { return ( ; } -FiveBadges.story = { - name: 'Five badges', -}; - export function ManyBadges(): JSX.Element { return ; } -ManyBadges.story = { - name: 'Many badges', -}; - export function ManyBadgesUserIsASubscriber(): JSX.Element { return ( ); } - -ManyBadgesUserIsASubscriber.story = { - name: 'Many badges, user is a subscriber', -}; diff --git a/ts/components/BadgeDialog.tsx b/ts/components/BadgeDialog.tsx index 2224d6e761..fafc7c7b49 100644 --- a/ts/components/BadgeDialog.tsx +++ b/ts/components/BadgeDialog.tsx @@ -15,7 +15,7 @@ import { BadgeImage } from './BadgeImage'; import { BadgeCarouselIndex } from './BadgeCarouselIndex'; import { BadgeSustainerInstructionsDialog } from './BadgeSustainerInstructionsDialog'; -type PropsType = Readonly<{ +export type PropsType = Readonly<{ areWeASubscriber: boolean; badges: ReadonlyArray; firstName?: string; diff --git a/ts/components/BetterAvatar.stories.tsx b/ts/components/BetterAvatar.stories.tsx index e07cae81c4..6a15a926f6 100644 --- a/ts/components/BetterAvatar.stories.tsx +++ b/ts/components/BetterAvatar.stories.tsx @@ -5,6 +5,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import { AvatarColors } from '../types/Colors'; import { GroupAvatarIcons, PersonalAvatarIcons } from '../types/Avatar'; @@ -28,7 +29,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/BetterAvatar', -}; +} satisfies Meta; export function Text(): JSX.Element { return ( diff --git a/ts/components/BetterAvatarBubble.stories.tsx b/ts/components/BetterAvatarBubble.stories.tsx index b4921bc95d..c4fa5f1ded 100644 --- a/ts/components/BetterAvatarBubble.stories.tsx +++ b/ts/components/BetterAvatarBubble.stories.tsx @@ -5,6 +5,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import { AvatarColors } from '../types/Colors'; import type { PropsType } from './BetterAvatarBubble'; @@ -25,7 +26,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/BetterAvatarBubble', -}; +} satisfies Meta; export function Children(): JSX.Element { return ( diff --git a/ts/components/Button.stories.tsx b/ts/components/Button.stories.tsx index 7ad08a7f3e..c745533933 100644 --- a/ts/components/Button.stories.tsx +++ b/ts/components/Button.stories.tsx @@ -3,12 +3,13 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './Button'; import { Button, ButtonSize, ButtonVariant } from './Button'; export default { title: 'Components/Button', -}; +} satisfies Meta; export function KitchenSink(): JSX.Element { return ( @@ -44,10 +45,6 @@ export function KitchenSink(): JSX.Element { ); } -KitchenSink.story = { - name: 'Kitchen sink', -}; - export function AriaLabel(): JSX.Element { return ( ); } - -CustomStyles.story = { - name: 'Custom styles', -}; diff --git a/ts/components/Button.tsx b/ts/components/Button.tsx index ee0485ed88..36dee96f50 100644 --- a/ts/components/Button.tsx +++ b/ts/components/Button.tsx @@ -33,13 +33,14 @@ export enum ButtonVariant { export enum ButtonIconType { audio = 'audio', + message = 'message', muted = 'muted', search = 'search', unmuted = 'unmuted', video = 'video', } -type PropsType = { +export type PropsType = { className?: string; disabled?: boolean; icon?: ButtonIconType; diff --git a/ts/components/CallManager.stories.tsx b/ts/components/CallManager.stories.tsx index 6cef11e1c3..d1bd130e82 100644 --- a/ts/components/CallManager.stories.tsx +++ b/ts/components/CallManager.stories.tsx @@ -3,8 +3,7 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; -import { boolean, select, text } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './CallManager'; import { CallManager } from './CallManager'; import { @@ -15,9 +14,12 @@ import { GroupCallConnectionState, GroupCallJoinState, } from '../types/Calling'; -import type { ConversationTypeType } from '../state/ducks/conversations'; -import type { AvatarColorType } from '../types/Colors'; +import type { + ConversationType, + ConversationTypeType, +} from '../state/ducks/conversations'; import { AvatarColors } from '../types/Colors'; +import { generateAci } from '../types/ServiceId'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import { fakeGetGroupCallVideoFrameSource } from '../test-both/helpers/fakeGetGroupCallVideoFrameSource'; import { setupI18n } from '../util/setupI18n'; @@ -32,13 +34,9 @@ const getConversation = () => getDefaultConversation({ id: '3051234567', avatarPath: undefined, - color: select( - 'Callee color', - AvatarColors, - 'ultramarine' as AvatarColorType - ), - title: text('Callee Title', 'Rick Sanchez'), - name: text('Callee Name', 'Rick Sanchez'), + color: AvatarColors[0], + title: 'Rick Sanchez', + name: 'Rick Sanchez', phoneNumber: '3051234567', profileName: 'Rick Sanchez', markedUnread: false, @@ -49,18 +47,14 @@ const getConversation = () => const getCommonActiveCallData = () => ({ conversation: getConversation(), joinedAt: Date.now(), - hasLocalAudio: boolean('hasLocalAudio', true), - hasLocalVideo: boolean('hasLocalVideo', false), - localAudioLevel: select('localAudioLevel', [0, 0.5, 1], 0), - viewMode: select( - 'viewMode', - [CallViewMode.Grid, CallViewMode.Presentation, CallViewMode.Speaker], - CallViewMode.Grid - ), - outgoingRing: boolean('outgoingRing', true), - pip: boolean('pip', false), - settingsDialogOpen: boolean('settingsDialogOpen', false), - showParticipantsList: boolean('showParticipantsList', false), + hasLocalAudio: true, + hasLocalVideo: false, + localAudioLevel: 0, + viewMode: CallViewMode.Paginated, + outgoingRing: true, + pip: false, + settingsDialogOpen: false, + showParticipantsList: false, }); const createProps = (storyProps: Partial = {}): PropsType => ({ @@ -70,6 +64,7 @@ const createProps = (storyProps: Partial = {}): PropsType => ({ bounceAppIconStart: action('bounce-app-icon-start'), bounceAppIconStop: action('bounce-app-icon-stop'), cancelCall: action('cancel-call'), + changeCallView: action('change-call-view'), closeNeedPermissionScreen: action('close-need-permission-screen'), declineCall: action('decline-call'), getGroupCallVideoFrameSource: (_: string, demuxId: number) => @@ -79,23 +74,25 @@ const createProps = (storyProps: Partial = {}): PropsType => ({ hangUpActiveCall: action('hang-up-active-call'), i18n, isGroupCallOutboundRingEnabled: true, + isGroupCallRaiseHandEnabled: true, + isGroupCallReactionsEnabled: true, keyChangeOk: action('key-change-ok'), me: { ...getDefaultConversation({ - color: select( - 'Caller color', - AvatarColors, - 'ultramarine' as AvatarColorType - ), - title: text('Caller Title', 'Morty Smith'), + color: AvatarColors[0], + title: 'Morty Smith', }), - uuid: 'cb0dd0c8-7393-41e9-a0aa-d631c4109541', + serviceId: generateAci(), }, notifyForCall: action('notify-for-call'), openSystemPreferencesAction: action('open-system-preferences-action'), playRingtone: action('play-ringtone'), renderDeviceSelection: () =>
, + renderEmojiPicker: () => <>EmojiPicker, + renderReactionPicker: () =>
, renderSafetyNumberViewer: (_: SafetyNumberProps) =>
, + sendGroupCallRaiseHand: action('send-group-call-raise-hand'), + sendGroupCallReaction: action('send-group-call-reaction'), setGroupCallVideoRequest: action('set-group-call-video-request'), setIsCallActive: action('set-is-call-active'), setLocalAudio: action('set-local-audio'), @@ -115,14 +112,15 @@ const createProps = (storyProps: Partial = {}): PropsType => ({ 'toggle-screen-recording-permissions-dialog' ), toggleSettings: action('toggle-settings'), - toggleSpeakerView: action('toggle-speaker-view'), isConversationTooBigToRing: false, pauseVoiceNotePlayer: action('pause-audio-player'), }); export default { title: 'Components/CallManager', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function NoCall(): JSX.Element { return ; @@ -155,12 +153,15 @@ export function OngoingGroupCall(): JSX.Element { callMode: CallMode.Group, connectionState: GroupCallConnectionState.Connected, conversationsWithSafetyNumberChanges: [], + conversationsByDemuxId: new Map(), deviceCount: 0, joinState: GroupCallJoinState.Joined, + localDemuxId: 1, maxDevices: 5, groupMembers: [], isConversationTooBigToRing: false, peekedParticipants: [], + raisedHands: new Set(), remoteParticipants: [], remoteAudioLevels: new Map(), }, @@ -183,10 +184,6 @@ export function RingingDirectCall(): JSX.Element { ); } -RingingDirectCall.story = { - name: 'Ringing (direct call)', -}; - export function RingingGroupCall(): JSX.Element { return ( (), deviceCount: 0, joinState: GroupCallJoinState.Joined, + localDemuxId: 1, maxDevices: 5, groupMembers: [], isConversationTooBigToRing: false, peekedParticipants: [], + raisedHands: new Set(), remoteParticipants: [], remoteAudioLevels: new Map(), }, @@ -262,7 +258,3 @@ export function GroupCallSafetyNumberChanged(): JSX.Element { /> ); } - -GroupCallSafetyNumberChanged.story = { - name: 'Group call - Safety Number Changed', -}; diff --git a/ts/components/CallManager.tsx b/ts/components/CallManager.tsx index 0d94e6a377..050642c062 100644 --- a/ts/components/CallManager.tsx +++ b/ts/components/CallManager.tsx @@ -15,6 +15,7 @@ import type { SafetyNumberProps } from './SafetyNumberChangeDialog'; import { SafetyNumberChangeDialog } from './SafetyNumberChangeDialog'; import type { ActiveCallType, + CallViewMode, GroupCallVideoRequest, PresentedSource, } from '../types/Calling'; @@ -32,6 +33,8 @@ import type { CancelCallType, DeclineCallType, KeyChangeOkType, + SendGroupCallRaiseHandType, + SendGroupCallReactionType, SetGroupCallVideoRequestType, SetLocalAudioType, SetLocalPreviewType, @@ -41,6 +44,9 @@ import type { } from '../state/ducks/calling'; import type { LocalizerType, ThemeType } from '../types/Util'; import { missingCaseError } from '../util/missingCaseError'; +import { CallingToastProvider } from './CallingToast'; +import type { SmartReactionPicker } from '../state/smart/ReactionPicker'; +import type { Props as ReactionPickerProps } from './conversation/ReactionPicker'; const GROUP_CALL_RING_DURATION = 60 * 1000; @@ -48,6 +54,7 @@ export type PropsType = { activeCall?: ActiveCallType; availableCameras: Array; cancelCall: (_: CancelCallType) => void; + changeCallView: (mode: CallViewMode) => void; closeNeedPermissionScreen: () => void; getGroupCallVideoFrameSource: ( conversationId: string, @@ -69,6 +76,9 @@ export type PropsType = { }; keyChangeOk: (_: KeyChangeOkType) => void; renderDeviceSelection: () => JSX.Element; + renderReactionPicker: ( + props: React.ComponentProps + ) => JSX.Element; renderSafetyNumberViewer: (props: SafetyNumberProps) => JSX.Element; startCall: (payload: StartCallType) => void; toggleParticipants: () => void; @@ -78,6 +88,8 @@ export type PropsType = { declineCall: (_: DeclineCallType) => void; i18n: LocalizerType; isGroupCallOutboundRingEnabled: boolean; + isGroupCallRaiseHandEnabled: boolean; + isGroupCallReactionsEnabled: boolean; me: ConversationType; notifyForCall: ( conversationId: string, @@ -86,6 +98,8 @@ export type PropsType = { ) => unknown; openSystemPreferencesAction: () => unknown; playRingtone: () => unknown; + sendGroupCallRaiseHand: (payload: SendGroupCallRaiseHandType) => void; + sendGroupCallReaction: (payload: SendGroupCallReactionType) => void; setGroupCallVideoRequest: (_: SetGroupCallVideoRequestType) => void; setIsCallActive: (_: boolean) => void; setLocalAudio: (_: SetLocalAudioType) => void; @@ -102,10 +116,9 @@ export type PropsType = { togglePip: () => void; toggleScreenRecordingPermissionsDialog: () => unknown; toggleSettings: () => void; - toggleSpeakerView: () => void; isConversationTooBigToRing: boolean; pauseVoiceNotePlayer: () => void; -}; +} & Pick; type ActiveCallManagerPropsType = PropsType & { activeCall: ActiveCallType; @@ -115,10 +128,13 @@ function ActiveCallManager({ activeCall, availableCameras, cancelCall, + changeCallView, closeNeedPermissionScreen, hangUpActiveCall, i18n, isGroupCallOutboundRingEnabled, + isGroupCallRaiseHandEnabled, + isGroupCallReactionsEnabled, keyChangeOk, getGroupCallVideoFrameSource, getPreferredBadge, @@ -126,7 +142,11 @@ function ActiveCallManager({ me, openSystemPreferencesAction, renderDeviceSelection, + renderEmojiPicker, + renderReactionPicker, renderSafetyNumberViewer, + sendGroupCallRaiseHand, + sendGroupCallReaction, setGroupCallVideoRequest, setLocalAudio, setLocalPreview, @@ -142,14 +162,12 @@ function ActiveCallManager({ togglePip, toggleScreenRecordingPermissionsDialog, toggleSettings, - toggleSpeakerView, pauseVoiceNotePlayer, }: ActiveCallManagerPropsType): JSX.Element { const { conversation, hasLocalAudio, hasLocalVideo, - joinedAt, peekedParticipants, pip, presentingSourcesAvailable, @@ -274,7 +292,7 @@ function ActiveCallManager({ ) : null} @@ -322,14 +340,20 @@ function ActiveCallManager({ <> {presentingSourcesAvailable && presentingSourcesAvailable.length ? ( ) : null} @@ -441,7 +464,11 @@ export function CallManager(props: PropsType): JSX.Element | null { if (activeCall) { // `props` should logically have an `activeCall` at this point, but TypeScript can't // figure that out, so we pass it in again. - return ; + return ( + + + + ); } // In the future, we may want to show the incoming call bar when a call is active. diff --git a/ts/components/CallParticipantCount.tsx b/ts/components/CallParticipantCount.tsx new file mode 100644 index 0000000000..5e711f562e --- /dev/null +++ b/ts/components/CallParticipantCount.tsx @@ -0,0 +1,51 @@ +// Copyright 2020 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import React from 'react'; +import type { LocalizerType } from '../types/Util'; + +export type PropsType = { + i18n: LocalizerType; + groupMemberCount?: number; + participantCount: number; + toggleParticipants: () => void; +}; + +export function CallParticipantCount({ + i18n, + groupMemberCount, + participantCount, + toggleParticipants, +}: PropsType): JSX.Element { + const count = participantCount || groupMemberCount || 1; + const innerText = i18n('icu:CallControls__InfoDisplay--participants', { + count: String(count), + }); + + // Call not started, can't click to show participants + if (!participantCount) { + return ( + + {innerText} + + ); + } + + return ( + + ); +} diff --git a/ts/components/CallScreen.stories.tsx b/ts/components/CallScreen.stories.tsx index 247c85fb55..384faa4d0c 100644 --- a/ts/components/CallScreen.stories.tsx +++ b/ts/components/CallScreen.stories.tsx @@ -2,11 +2,15 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { times } from 'lodash'; -import { boolean, select, number } from '@storybook/addon-knobs'; +import { sample, times } from 'lodash'; import { action } from '@storybook/addon-actions'; -import type { GroupCallRemoteParticipantType } from '../types/Calling'; +import type { Meta } from '@storybook/react'; +import type { + ActiveCallReactionsType, + ActiveGroupCallType, + GroupCallRemoteParticipantType, +} from '../types/Calling'; import { CallMode, CallViewMode, @@ -14,20 +18,24 @@ import { GroupCallConnectionState, GroupCallJoinState, } from '../types/Calling'; +import { generateAci } from '../types/ServiceId'; import type { ConversationType } from '../state/ducks/conversations'; import { AvatarColors } from '../types/Colors'; import type { PropsType } from './CallScreen'; -import { CallScreen } from './CallScreen'; +import { CallScreen as UnwrappedCallScreen } from './CallScreen'; +import { DEFAULT_PREFERRED_REACTION_EMOJI } from '../reactions/constants'; import { setupI18n } from '../util/setupI18n'; import { missingCaseError } from '../util/missingCaseError'; import { getDefaultConversation, - getDefaultConversationWithUuid, + getDefaultConversationWithServiceId, } from '../test-both/helpers/getDefaultConversation'; import { fakeGetGroupCallVideoFrameSource } from '../test-both/helpers/fakeGetGroupCallVideoFrameSource'; import enMessages from '../../_locales/en/messages.json'; +import { CallingToastProvider, useCallingToasts } from './CallingToast'; -const MAX_PARTICIPANTS = 64; +const MAX_PARTICIPANTS = 75; +const LOCAL_DEMUX_ID = 1; const i18n = setupI18n('en', enMessages); @@ -46,6 +54,7 @@ type OverridePropsBase = { hasLocalVideo?: boolean; localAudioLevel?: number; viewMode?: CallViewMode; + reactions?: ActiveCallReactionsType; }; type DirectCallOverrideProps = OverridePropsBase & { @@ -58,7 +67,9 @@ type GroupCallOverrideProps = OverridePropsBase & { callMode: CallMode.Group; connectionState?: GroupCallConnectionState; peekedParticipants?: Array; + raisedHands?: Set; remoteParticipants?: Array; + remoteAudioLevel?: number; }; const createActiveDirectCallProp = ( @@ -66,18 +77,11 @@ const createActiveDirectCallProp = ( ) => ({ callMode: CallMode.Direct as CallMode.Direct, conversation, - callState: select( - 'callState', - CallState, - overrideProps.callState || CallState.Accepted - ), + callState: overrideProps.callState ?? CallState.Accepted, peekedParticipants: [] as [], remoteParticipants: [ { - hasRemoteVideo: boolean( - 'hasRemoteVideo', - Boolean(overrideProps.hasRemoteVideo) - ), + hasRemoteVideo: overrideProps.hasRemoteVideo ?? false, presenting: false, title: 'test', }, @@ -90,12 +94,28 @@ const createActiveDirectCallProp = ( ], }); +const getConversationsByDemuxId = (overrideProps: GroupCallOverrideProps) => { + const conversationsByDemuxId = new Map( + overrideProps.remoteParticipants?.map((participant, index) => [ + participant.demuxId, + getDefaultConversationWithServiceId({ + isBlocked: index === 10 || index === MAX_PARTICIPANTS - 1, + title: `Participant ${index + 1}`, + }), + ]) + ); + conversationsByDemuxId.set(LOCAL_DEMUX_ID, conversation); + return conversationsByDemuxId; +}; + const createActiveGroupCallProp = (overrideProps: GroupCallOverrideProps) => ({ callMode: CallMode.Group as CallMode.Group, connectionState: overrideProps.connectionState || GroupCallConnectionState.Connected, conversationsWithSafetyNumberChanges: [], + conversationsByDemuxId: getConversationsByDemuxId(overrideProps), joinState: GroupCallJoinState.Joined, + localDemuxId: LOCAL_DEMUX_ID, maxDevices: 5, deviceCount: (overrideProps.remoteParticipants || []).length, groupMembers: overrideProps.remoteParticipants || [], @@ -104,18 +124,15 @@ const createActiveGroupCallProp = (overrideProps: GroupCallOverrideProps) => ({ isConversationTooBigToRing: false, peekedParticipants: overrideProps.peekedParticipants || overrideProps.remoteParticipants || [], + raisedHands: overrideProps.raisedHands || new Set(), remoteParticipants: overrideProps.remoteParticipants || [], remoteAudioLevels: new Map( overrideProps.remoteParticipants?.map((_participant, index) => [ index, - number('remoteAudioLevel', 0, { - range: true, - min: 0, - max: 1, - step: 0.01, - }), + overrideProps.remoteAudioLevel ?? 0, ]) ), + reactions: overrideProps.reactions || [], }); const createActiveCallProp = ( @@ -124,24 +141,10 @@ const createActiveCallProp = ( const baseResult = { joinedAt: Date.now(), conversation, - hasLocalAudio: boolean( - 'hasLocalAudio', - overrideProps.hasLocalAudio || false - ), - hasLocalVideo: boolean( - 'hasLocalVideo', - overrideProps.hasLocalVideo || false - ), - localAudioLevel: select( - 'localAudioLevel', - [0, 0.5, 1], - overrideProps.localAudioLevel || 0 - ), - viewMode: select( - 'viewMode', - [CallViewMode.Grid, CallViewMode.Speaker, CallViewMode.Presentation], - overrideProps.viewMode || CallViewMode.Grid - ), + hasLocalAudio: overrideProps.hasLocalAudio ?? false, + hasLocalVideo: overrideProps.hasLocalVideo ?? false, + localAudioLevel: overrideProps.localAudioLevel ?? 0, + viewMode: overrideProps.viewMode ?? CallViewMode.Overflow, outgoingRing: true, pip: false, settingsDialogOpen: false, @@ -164,26 +167,33 @@ const createProps = ( } ): PropsType => ({ activeCall: createActiveCallProp(overrideProps), + changeCallView: action('change-call-view'), getGroupCallVideoFrameSource: fakeGetGroupCallVideoFrameSource, getPresentingSources: action('get-presenting-sources'), hangUpActiveCall: action('hang-up'), i18n, + isGroupCallRaiseHandEnabled: true, + isGroupCallReactionsEnabled: true, me: getDefaultConversation({ color: AvatarColors[1], id: '6146087e-f7ef-457e-9a8d-47df1fdd6b25', name: 'Morty Smith', profileName: 'Morty Smith', title: 'Morty Smith', - uuid: '3c134598-eecb-42ab-9ad3-2b0873f771b2', + serviceId: generateAci(), }), openSystemPreferencesAction: action('open-system-preferences-action'), + renderEmojiPicker: () => <>EmojiPicker, + renderReactionPicker: () =>
, + sendGroupCallRaiseHand: action('send-group-call-raise-hand'), + sendGroupCallReaction: action('send-group-call-reaction'), setGroupCallVideoRequest: action('set-group-call-video-request'), setLocalAudio: action('set-local-audio'), setLocalPreview: action('set-local-preview'), setLocalVideo: action('set-local-video'), setPresenting: action('toggle-presenting'), setRendererCanvas: action('set-renderer-canvas'), - stickyControls: boolean('stickyControls', false), + stickyControls: false, switchToPresentationView: action('switch-to-presentation-view'), switchFromPresentationView: action('switch-from-presentation-view'), toggleParticipants: action('toggle-participants'), @@ -192,12 +202,21 @@ const createProps = ( 'toggle-screen-recording-permissions-dialog' ), toggleSettings: action('toggle-settings'), - toggleSpeakerView: action('toggle-speaker-view'), }); +function CallScreen(props: ReturnType): JSX.Element { + return ( + + + + ); +} + export default { title: 'Components/CallScreen', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function Default(): JSX.Element { return ; @@ -214,11 +233,7 @@ export function PreRing(): JSX.Element { ); } -PreRing.story = { - name: 'Pre-Ring', -}; - -export const _Ringing = (): JSX.Element => { +export function Ringing(): JSX.Element { return ( { })} /> ); -}; +} -export const _Reconnecting = (): JSX.Element => { +export function Reconnecting(): JSX.Element { return ( { })} /> ); -}; +} -export const _Ended = (): JSX.Element => { +export function Ended(): JSX.Element { return ( { })} /> ); -}; +} export function HasLocalAudio(): JSX.Element { return ( @@ -262,10 +277,6 @@ export function HasLocalAudio(): JSX.Element { ); } -HasLocalAudio.story = { - name: 'hasLocalAudio', -}; - export function HasLocalVideo(): JSX.Element { return ( ({ - demuxId: index, - hasRemoteAudio: index % 3 !== 0, - hasRemoteVideo: index % 4 !== 0, - presenting: false, - sharingScreen: false, - videoAspectRatio: 1.3, - ...getDefaultConversationWithUuid({ - isBlocked: index === 10 || index === MAX_PARTICIPANTS - 1, - title: `Participant ${index + 1}`, - }), -})); - -export function GroupCallMany(): JSX.Element { +export function GroupCallYourHandRaised(): JSX.Element { return ( ); } -GroupCallMany.story = { - name: 'Group call - Many', -}; +// We generate these upfront so that the list is stable when you move the slider. +const allRemoteParticipants = times(MAX_PARTICIPANTS).map(index => ({ + aci: generateAci(), + demuxId: index, + hasRemoteAudio: index % 3 !== 0, + hasRemoteVideo: index % 4 !== 0, + isHandRaised: (index - 3) % 10 === 0, + presenting: false, + sharingScreen: false, + videoAspectRatio: Math.random() < 0.7 ? 1.3 : Math.random() * 0.4 + 0.6, + ...getDefaultConversationWithServiceId({ + isBlocked: index === 10 || index === MAX_PARTICIPANTS - 1, + title: `Participant ${index + 1}`, + }), +})); + +export function GroupCallManyPaginated(): JSX.Element { + const props = createProps({ + callMode: CallMode.Group, + remoteParticipants: allRemoteParticipants, + viewMode: CallViewMode.Paginated, + }); + + return ; +} +export function GroupCallManyPaginatedEveryoneTalking(): JSX.Element { + const [props] = React.useState( + createProps({ + callMode: CallMode.Group, + remoteParticipants: allRemoteParticipants, + viewMode: CallViewMode.Paginated, + }) + ); + + const activeCall = useMakeEveryoneTalk( + props.activeCall as ActiveGroupCallType + ); + + return ; +} + +export function GroupCallManyOverflow(): JSX.Element { + return ( + + ); +} + +export function GroupCallManyOverflowEveryoneTalking(): JSX.Element { + const [props] = React.useState( + createProps({ + callMode: CallMode.Group, + remoteParticipants: allRemoteParticipants, + viewMode: CallViewMode.Overflow, + }) + ); + + const activeCall = useMakeEveryoneTalk( + props.activeCall as ActiveGroupCallType + ); + + return ; +} + +export function GroupCallSpeakerView(): JSX.Element { + return ( + + ); +} export function GroupCallReconnecting(): JSX.Element { return ( @@ -370,16 +443,18 @@ export function GroupCallReconnecting(): JSX.Element { connectionState: GroupCallConnectionState.Reconnecting, remoteParticipants: [ { + aci: generateAci(), demuxId: 0, hasRemoteAudio: true, hasRemoteVideo: true, + isHandRaised: false, presenting: false, sharingScreen: false, videoAspectRatio: 1.3, ...getDefaultConversation({ isBlocked: false, title: 'Tyler', - uuid: '33871c64-0c22-45ce-8aa4-0ec237ac4a31', + serviceId: generateAci(), }), }, ], @@ -388,10 +463,6 @@ export function GroupCallReconnecting(): JSX.Element { ); } -GroupCallReconnecting.story = { - name: 'Group call - reconnecting', -}; - export function GroupCall0(): JSX.Element { return ( ({ + ...participant, + presenting: index === 1, + sharingScreen: index === 1, + })) + ); + + React.useEffect(() => { + setTimeout( + () => setRemoteParticipants(allRemoteParticipants.slice(0, 5)), + 1000 + ); + }); + + return ( + + ); +} + +function ToastEmitter(): null { + const { showToast } = useCallingToasts(); + const toastCount = React.useRef(0); + React.useEffect(() => { + const interval = setInterval(() => { + const autoClose = toastCount.current % 2 === 0; + showToast({ + key: Date.now().toString(), + content: `${ + autoClose ? 'Disappearing' : 'Non-disappearing' + } toast sent: ${Date.now()}`, + dismissable: true, + autoClose, + }); + toastCount.current += 1; + }, 1500); + return () => clearInterval(interval); + }, [showToast]); + return null; +} + +export function CallScreenToastAPalooza(): JSX.Element { + return ( + + + + + ); +} + +function useMakeEveryoneTalk( + activeCall: ActiveGroupCallType, + frequency = 2000 +) { + const [call, setCall] = React.useState(activeCall); + React.useEffect(() => { + const interval = setInterval(() => { + const idxToStartSpeaking = Math.floor( + Math.random() * call.remoteParticipants.length + ); + + const demuxIdToStartSpeaking = ( + call.remoteParticipants[ + idxToStartSpeaking + ] as GroupCallRemoteParticipantType + ).demuxId; + + const remoteAudioLevels = new Map(); + + for (const [demuxId] of call.remoteAudioLevels.entries()) { + if (demuxId === demuxIdToStartSpeaking) { + remoteAudioLevels.set(demuxId, 1); + } else { + remoteAudioLevels.set(demuxId, 0); + } + } + setCall(state => ({ + ...state, + remoteParticipants: state.remoteParticipants.map((part, idx) => { + return { + ...part, + hasRemoteAudio: + idx === idxToStartSpeaking ? true : part.hasRemoteAudio, + speakerTime: + idx === idxToStartSpeaking + ? Date.now() + : (part as GroupCallRemoteParticipantType).speakerTime, + }; + }), + remoteAudioLevels, + })); + }, frequency); + return () => clearInterval(interval); + }, [frequency, call]); + return call; +} + +export function GroupCallReactions(): JSX.Element { + const remoteParticipants = allRemoteParticipants.slice(0, 5); + const [props] = React.useState( + createProps({ + callMode: CallMode.Group, + remoteParticipants, + viewMode: CallViewMode.Overflow, + }) + ); + + const activeCall = useReactionsEmitter( + props.activeCall as ActiveGroupCallType + ); + + return ; +} + +export function GroupCallReactionsSpam(): JSX.Element { + const remoteParticipants = allRemoteParticipants.slice(0, 5); + const [props] = React.useState( + createProps({ + callMode: CallMode.Group, + remoteParticipants, + viewMode: CallViewMode.Overflow, + }) + ); + + const activeCall = useReactionsEmitter( + props.activeCall as ActiveGroupCallType, + 250 + ); + + return ; +} + +export function GroupCallReactionsBurstInOrder(): JSX.Element { + const timestamp = Date.now(); + const remoteParticipants = allRemoteParticipants.slice(0, 5); + const reactions = remoteParticipants.map((participant, i) => { + const { demuxId } = participant; + const value = + DEFAULT_PREFERRED_REACTION_EMOJI[ + i % DEFAULT_PREFERRED_REACTION_EMOJI.length + ]; + return { timestamp, demuxId, value }; + }); + const [props] = React.useState( + createProps({ + callMode: CallMode.Group, + remoteParticipants, + viewMode: CallViewMode.Overflow, + reactions, + }) + ); + + return ; +} + +function useReactionsEmitter( + activeCall: ActiveGroupCallType, + frequency = 2000, + removeAfter = 5000 +) { + const [call, setCall] = React.useState(activeCall); + React.useEffect(() => { + const interval = setInterval(() => { + setCall(state => { + const timeNow = Date.now(); + const expireAt = timeNow - removeAfter; + + const participantIndex = Math.floor( + Math.random() * call.remoteParticipants.length + ); + const { demuxId } = call.remoteParticipants[participantIndex]; + + const reactions: ActiveCallReactionsType = [ + ...(state.reactions ?? []).filter( + ({ timestamp }) => timestamp > expireAt + ), + { + timestamp: timeNow, + demuxId, + value: sample(DEFAULT_PREFERRED_REACTION_EMOJI) as string, + }, + ]; + + return { + ...state, + reactions, + }; + }); + }, frequency); + return () => clearInterval(interval); + }, [frequency, removeAfter, call]); + return call; +} diff --git a/ts/components/CallScreen.tsx b/ts/components/CallScreen.tsx index 41d8a63dda..48ec471cee 100644 --- a/ts/components/CallScreen.tsx +++ b/ts/components/CallScreen.tsx @@ -3,27 +3,34 @@ import type { ReactNode } from 'react'; import React, { useState, useRef, useEffect, useCallback } from 'react'; -import { noop } from 'lodash'; +import { isEqual, noop } from 'lodash'; import classNames from 'classnames'; import type { VideoFrameSource } from '@signalapp/ringrtc'; import type { ActiveCallStateType, + SendGroupCallRaiseHandType, + SendGroupCallReactionType, SetLocalAudioType, SetLocalPreviewType, SetLocalVideoType, SetRendererCanvasType, } from '../state/ducks/calling'; import { Avatar, AvatarSize } from './Avatar'; -import { CallingHeader } from './CallingHeader'; +import { CallingHeader, getCallViewIconClassname } from './CallingHeader'; import { CallingPreCallInfo, RingMode } from './CallingPreCallInfo'; import { CallingButton, CallingButtonType } from './CallingButton'; +import { Button, ButtonVariant } from './Button'; +import { TooltipPlacement } from './Tooltip'; import { CallBackgroundBlur } from './CallBackgroundBlur'; import type { ActiveCallType, + ActiveCallReactionsType, + ConversationsByDemuxIdType, GroupCallVideoRequest, PresentedSource, } from '../types/Calling'; import { + CALLING_REACTIONS_LIFETIME, CallMode, CallViewMode, CallState, @@ -32,14 +39,21 @@ import { } from '../types/Calling'; import { AvatarColors } from '../types/Colors'; import type { ConversationType } from '../state/ducks/conversations'; -import { CallingToastManager } from './CallingToastManager'; +import { + CallingButtonToastsContainer, + useScreenSharingStoppedToast, +} from './CallingToastManager'; import { DirectCallRemoteParticipant } from './DirectCallRemoteParticipant'; import { GroupCallRemoteParticipants } from './GroupCallRemoteParticipants'; +import { CallParticipantCount } from './CallParticipantCount'; import type { LocalizerType } from '../types/Util'; import { NeedsScreenRecordingPermissionsModal } from './NeedsScreenRecordingPermissionsModal'; import { missingCaseError } from '../util/missingCaseError'; import * as KeyboardLayout from '../services/keyboardLayout'; -import { useActivateSpeakerViewOnPresenting } from '../hooks/useActivateSpeakerViewOnPresenting'; +import { + usePresenter, + useActivateSpeakerViewOnPresenting, +} from '../hooks/useActivateSpeakerViewOnPresenting'; import { CallingAudioIndicator, SPEAKING_LINGER_MS, @@ -49,6 +63,19 @@ import { useKeyboardShortcuts, } from '../hooks/useKeyboardShortcuts'; import { useValueAtFixedRate } from '../hooks/useValueAtFixedRate'; +import { isReconnecting as callingIsReconnecting } from '../util/callingIsReconnecting'; +import { usePrevious } from '../hooks/usePrevious'; +import { + CallingToastProvider, + PersistentCallingToast, + useCallingToasts, +} from './CallingToast'; +import { Spinner } from './Spinner'; +import { handleOutsideClick } from '../util/handleOutsideClick'; +import type { Props as ReactionPickerProps } from './conversation/ReactionPicker'; +import type { SmartReactionPicker } from '../state/smart/ReactionPicker'; +import { Emoji } from './emoji/Emoji'; +import { CallingRaisedHandsList } from './CallingRaisedHandsList'; export type PropsType = { activeCall: ActiveCallType; @@ -57,9 +84,15 @@ export type PropsType = { groupMembers?: Array>; hangUpActiveCall: (reason: string) => void; i18n: LocalizerType; - joinedAt?: number; + isGroupCallRaiseHandEnabled: boolean; + isGroupCallReactionsEnabled: boolean; me: ConversationType; openSystemPreferencesAction: () => unknown; + renderReactionPicker: ( + props: React.ComponentProps + ) => JSX.Element; + sendGroupCallRaiseHand: (payload: SendGroupCallRaiseHandType) => void; + sendGroupCallReaction: (payload: SendGroupCallReactionType) => void; setGroupCallVideoRequest: ( _: Array, speakerHeight: number @@ -76,14 +109,8 @@ export type PropsType = { togglePip: () => void; toggleScreenRecordingPermissionsDialog: () => unknown; toggleSettings: () => void; - toggleSpeakerView: () => void; -}; - -type DirectCallHeaderMessagePropsType = { - i18n: LocalizerType; - callState: CallState; - joinedAt?: number; -}; + changeCallView: (mode: CallViewMode) => void; +} & Pick; export const isInSpeakerView = ( call: Pick | undefined @@ -94,17 +121,21 @@ export const isInSpeakerView = ( ); }; -function DirectCallHeaderMessage({ - callState, - i18n, +const REACTIONS_TOASTS_TRANSITION_FROM = { + opacity: 0, +}; + +function CallDuration({ joinedAt, -}: DirectCallHeaderMessagePropsType): JSX.Element | null { +}: { + joinedAt: number | null; +}): JSX.Element | null { const [acceptedDuration, setAcceptedDuration] = useState< number | undefined >(); useEffect(() => { - if (!joinedAt) { + if (joinedAt == null) { return noop; } // It's really jumpy with a value of 500ms. @@ -114,32 +145,29 @@ function DirectCallHeaderMessage({ return clearInterval.bind(null, interval); }, [joinedAt]); - if (callState === CallState.Reconnecting) { - return <>{i18n('icu:callReconnecting')}; - } - if (callState === CallState.Accepted && acceptedDuration) { - return ( - <> - {i18n('icu:callDuration', { - duration: renderDuration(acceptedDuration), - })} - - ); + if (acceptedDuration) { + return <>{renderDuration(acceptedDuration)}; } return null; } export function CallScreen({ activeCall, + changeCallView, getGroupCallVideoFrameSource, getPresentingSources, groupMembers, hangUpActiveCall, i18n, - joinedAt, + isGroupCallRaiseHandEnabled, + isGroupCallReactionsEnabled, me, openSystemPreferencesAction, + renderEmojiPicker, + renderReactionPicker, setGroupCallVideoRequest, + sendGroupCallRaiseHand, + sendGroupCallReaction, setLocalAudio, setLocalVideo, setLocalPreview, @@ -152,7 +180,6 @@ export function CallScreen({ togglePip, toggleScreenRecordingPermissionsDialog, toggleSettings, - toggleSpeakerView, }: PropsType): JSX.Element { const { conversation, @@ -162,7 +189,7 @@ export function CallScreen({ presentingSource, remoteParticipants, showNeedsScreenRecordingPermissionsWarning, - showParticipantsList, + reactions, } = activeCall; const isSpeaking = useValueAtFixedRate( @@ -203,6 +230,19 @@ export function CallScreen({ hangUpActiveCall('button click'); }, [hangUpActiveCall]); + const moreOptionsMenuRef = React.useRef(null); + const moreOptionsButtonRef = React.useRef(null); + const reactionPickerRef = React.useRef(null); + const [showMoreOptions, setShowMoreOptions] = useState(false); + const toggleMoreOptions = useCallback(() => { + setShowMoreOptions(prevValue => !prevValue); + }, []); + + const [showRaisedHandsList, setShowRaisedHandsList] = useState(false); + const toggleRaisedHandsList = useCallback(() => { + setShowRaisedHandsList(prevValue => !prevValue); + }, []); + const [controlsHover, setControlsHover] = useState(false); const onControlsMouseEnter = useCallback(() => { @@ -225,14 +265,14 @@ export function CallScreen({ }, [setLocalPreview, setRendererCanvas]); useEffect(() => { - if (!showControls || stickyControls || controlsHover) { + if (!showControls || showMoreOptions || stickyControls || controlsHover) { return noop; } const timer = setTimeout(() => { setShowControls(false); }, 5000); return clearTimeout.bind(null, timer); - }, [showControls, stickyControls, controlsHover]); + }, [showControls, showMoreOptions, stickyControls, controlsHover]); useEffect(() => { const handleKeyDown = (event: KeyboardEvent): void => { @@ -261,6 +301,25 @@ export function CallScreen({ }; }, [toggleAudio, toggleVideo]); + useEffect(() => { + if (!showMoreOptions) { + return noop; + } + return handleOutsideClick( + () => { + setShowMoreOptions(false); + return true; + }, + { + containerElements: [moreOptionsButtonRef, moreOptionsMenuRef], + name: 'CallScreen.moreOptions', + } + ); + }, [showMoreOptions]); + + useScreenSharingStoppedToast({ activeCall, i18n }); + useViewModeChangedToast({ activeCall, i18n }); + const currentPresenter = remoteParticipants.find( participant => participant.presenting ); @@ -270,14 +329,15 @@ export function CallScreen({ ); const isSendingVideo = hasLocalVideo || presentingSource; + const isReconnecting: boolean = callingIsReconnecting(activeCall); let isRinging: boolean; let hasCallStarted: boolean; - let headerMessage: ReactNode | undefined; - let headerTitle: string | undefined; let isConnected: boolean; let participantCount: number; let remoteParticipantsElement: ReactNode; + let conversationsByDemuxId: ConversationsByDemuxIdType; + let localDemuxId: number | undefined; switch (activeCall.callMode) { case CallMode.Direct: { @@ -285,21 +345,15 @@ export function CallScreen({ activeCall.callState === CallState.Prering || activeCall.callState === CallState.Ringing; hasCallStarted = !isRinging; - headerMessage = ( - - ); - headerTitle = isRinging ? undefined : conversation.title; isConnected = activeCall.callState === CallState.Accepted; participantCount = isConnected ? 2 : 0; + conversationsByDemuxId = new Map(); remoteParticipantsElement = hasCallStarted ? ( ) : ( @@ -314,27 +368,20 @@ export function CallScreen({ !(groupMembers?.length === 1 && groupMembers[0].id === me.id); hasCallStarted = activeCall.joinState !== GroupCallJoinState.NotJoined; participantCount = activeCall.remoteParticipants.length + 1; - - if (isRinging) { - headerTitle = undefined; - } else if (currentPresenter) { - headerTitle = i18n('icu:calling__presenting--person-ongoing', { - name: currentPresenter.title, - }); - } else if (!activeCall.remoteParticipants.length) { - headerTitle = i18n('icu:calling__in-this-call--zero'); - } + conversationsByDemuxId = activeCall.conversationsByDemuxId; + localDemuxId = activeCall.localDemuxId; isConnected = activeCall.connectionState === GroupCallConnectionState.Connected; remoteParticipantsElement = ( ); break; @@ -345,15 +392,9 @@ export function CallScreen({ let lonelyInCallNode: ReactNode; let localPreviewNode: ReactNode; - const isLonelyInGroup = - activeCall.callMode === CallMode.Group && - !activeCall.remoteParticipants.length; + const isLonelyInCall = !activeCall.remoteParticipants.length; - const isLonelyInDirectCall = - activeCall.callMode === CallMode.Direct && - activeCall.callState !== CallState.Accepted; - - if (isLonelyInGroup || isLonelyInDirectCall) { + if (isLonelyInCall) { lonelyInCallNode = (
) : ( - ` needs it - // to determine blurring. - sharedGroupNames={[]} - size={AvatarSize.EIGHTY} - /> +
{i18n('icu:calling__your-video-is-off')}
@@ -417,7 +442,7 @@ export function CallScreen({ title={me.title} // See comment above about `sharedGroupNames`. sharedGroupNames={[]} - size={AvatarSize.EIGHTY} + size={AvatarSize.FORTY} /> ); @@ -438,14 +463,16 @@ export function CallScreen({ const isAudioOnly = !hasLocalVideo && !hasRemoteVideo; + const controlsFadedOut = !showControls && !isAudioOnly && isConnected; const controlsFadeClass = classNames({ 'module-ongoing-call__controls--fadeIn': (showControls || isAudioOnly) && !isConnected, - 'module-ongoing-call__controls--fadeOut': - !showControls && !isAudioOnly && isConnected, + 'module-ongoing-call__controls--fadeOut': controlsFadedOut, }); const isGroupCall = activeCall.callMode === CallMode.Group; + const isMoreOptionsButtonEnabled = + isGroupCall && (isGroupCallRaiseHandEnabled || isGroupCallReactionsEnabled); let presentingButtonType: CallingButtonType; if (presentingSource) { @@ -456,6 +483,150 @@ export function CallScreen({ presentingButtonType = CallingButtonType.PRESENTING_OFF; } + const raisedHands = + activeCall.callMode === CallMode.Group ? activeCall.raisedHands : undefined; + + // This is the value of our hand raised as seen by remote clients. We should prefer + // to use it in UI so the user understands what remote clients see. + const syncedLocalHandRaised = isHandRaised(raisedHands, localDemuxId); + + // Don't call setLocalHandRaised because it only sets local state. Instead call + // toggleRaiseHand() which will set ringrtc state and call setLocalHandRaised. + const [localHandRaised, setLocalHandRaised] = useState( + syncedLocalHandRaised + ); + const previousLocalHandRaised = usePrevious(localHandRaised, localHandRaised); + const toggleRaiseHand = useCallback( + (raise?: boolean) => { + const nextValue = raise ?? !localHandRaised; + if (nextValue === previousLocalHandRaised) { + return; + } + + setLocalHandRaised(nextValue); + // It's possible that the ringrtc call can fail due to flaky network connection. + // In that case, local and remote state (localHandRaised and raisedHands) can + // get out of sync. The user might need to manually toggle raise hand to get to + // a coherent state. It would be nice if this returned a Promise (but it doesn't) + sendGroupCallRaiseHand({ + conversationId: conversation.id, + raise: nextValue, + }); + }, + [ + localHandRaised, + previousLocalHandRaised, + conversation.id, + sendGroupCallRaiseHand, + ] + ); + + const renderRaisedHandsToast = React.useCallback( + (hands: Array) => { + const names = hands.map(demuxId => + demuxId === localDemuxId + ? i18n('icu:you') + : conversationsByDemuxId.get(demuxId)?.title + ); + + let message: string; + let buttonOverride: JSX.Element | undefined; + const count = names.length; + switch (count) { + case 0: + return undefined; + case 1: + if (names[0] === i18n('icu:you')) { + message = i18n('icu:CallControls__RaiseHandsToast--you'); + buttonOverride = ( + + ); + } else { + message = i18n('icu:CallControls__RaiseHandsToast--one', { + name: names[0], + }); + } + break; + case 2: + message = i18n('icu:CallControls__RaiseHandsToast--two', { + name: names[0], + otherName: names[1], + }); + break; + default: + message = i18n('icu:CallControls__RaiseHandsToast--more', { + name: names[0], + otherName: names[1], + overflowCount: names.length - 2, + }); + } + return ( +
+ + {message} + {buttonOverride || ( + + )} +
+ ); + }, + [i18n, localDemuxId, conversationsByDemuxId, toggleRaiseHand] + ); + + const raisedHandsCount: number = raisedHands?.size ?? 0; + + const callStatus: ReactNode | string = React.useMemo(() => { + if (isRinging) { + return i18n('icu:outgoingCallRinging'); + } + if (isReconnecting) { + return i18n('icu:callReconnecting'); + } + if (isGroupCall) { + return ( + + ); + } + // joinedAt is only available for direct calls + if (isConnected) { + return ; + } + if (hasLocalVideo) { + return i18n('icu:ContactListItem__menu__video-call'); + } + if (hasLocalAudio) { + return i18n('icu:CallControls__InfoDisplay--audio-call'); + } + return null; + }, [ + i18n, + isRinging, + isConnected, + activeCall.joinedAt, + isReconnecting, + isGroupCall, + participantCount, + hasLocalVideo, + hasLocalAudio, + toggleParticipants, + ]); + return (
{ setShowControls(true); @@ -475,6 +652,29 @@ export function CallScreen({ }} role="group" > + {isReconnecting ? ( + + + + {i18n('icu:callReconnecting')} + + + ) : null} + + {isLonelyInCall && !isRinging ? ( + + {i18n('icu:calling__in-this-call--zero')} + + ) : null} + + {currentPresenter ? ( + + {i18n('icu:calling__presenting--person-ongoing', { + name: currentPresenter.title, + })} + + ) : null} + {showNeedsScreenRecordingPermissionsWarning ? ( ) : null} - -
+
{isRinging && ( - + <> +
+ + )} {remoteParticipantsElement} {lonelyInCallNode} + + {raisedHands && raisedHandsCount > 0 && ( + <> + + {showRaisedHandsList && ( + setShowRaisedHandsList(false)} + onLowerMyHand={() => { + toggleRaiseHand(false); + setShowRaisedHandsList(false); + }} + localDemuxId={localDemuxId} + conversationsByDemuxId={conversationsByDemuxId} + raisedHands={raisedHands} + localHandRaised={syncedLocalHandRaised} + /> + )} + + )}
- {/* This layout-only element is not ideal. - See the comment in _modules.css for more. */} -
+
- +
{conversation.title}
+
{callStatus}
+
+ + + + {showMoreOptions && ( +
+
+ {isGroupCallReactionsEnabled && + renderReactionPicker({ + ref: reactionPickerRef, + onClose: () => setShowMoreOptions(false), + onPick: emoji => { + setShowMoreOptions(false); + sendGroupCallReaction({ + conversationId: conversation.id, + value: emoji, + }); + }, + renderEmojiPicker, + })} + {isGroupCallRaiseHandEnabled && ( + + )} +
+
+ )} + +
+ + + + {isMoreOptionsButtonEnabled && ( +
+ +
+ )} +
+
- - - -
-
- {localPreviewNode} - + > + +
+ {localPreviewNode ? ( +
+ {localPreviewNode} + {!isSendingVideo && ( +
+ )} + + {syncedLocalHandRaised && ( +
+ )} +
+ ) : ( +
+ )}
); @@ -591,3 +920,139 @@ function renderDuration(ms: number): string { } return `${mins}:${secs}`; } + +function useViewModeChangedToast({ + activeCall, + i18n, +}: { + activeCall: ActiveCallType; + i18n: LocalizerType; +}): void { + const { viewMode } = activeCall; + const previousViewMode = usePrevious(viewMode, viewMode); + const presenterAci = usePresenter(activeCall.remoteParticipants); + + const VIEW_MODE_CHANGED_TOAST_KEY = 'view-mode-changed'; + const { showToast, hideToast } = useCallingToasts(); + + useEffect(() => { + if (viewMode !== previousViewMode) { + if ( + // If this is an automated change to presentation mode, don't show toast + viewMode === CallViewMode.Presentation || + // if this is an automated change away from presentation mode, don't show toast + (previousViewMode === CallViewMode.Presentation && !presenterAci) + ) { + return; + } + + hideToast(VIEW_MODE_CHANGED_TOAST_KEY); + showToast({ + key: VIEW_MODE_CHANGED_TOAST_KEY, + content: ( +
+ + {i18n('icu:calling__view_mode--updated')} +
+ ), + autoClose: true, + }); + } + }, [ + showToast, + hideToast, + i18n, + activeCall, + viewMode, + previousViewMode, + presenterAci, + ]); +} + +type CallingReactionsToastsType = { + reactions: ActiveCallReactionsType | undefined; + conversationsByDemuxId: Map; + localDemuxId: number | undefined; + i18n: LocalizerType; +}; + +function useReactionsToast(props: CallingReactionsToastsType): void { + const { reactions, conversationsByDemuxId, localDemuxId, i18n } = props; + const [previousReactions, setPreviousReactions] = React.useState< + ActiveCallReactionsType | undefined + >(undefined); + const { showToast } = useCallingToasts(); + + useEffect(() => { + setPreviousReactions(reactions); + }, [reactions]); + + useEffect(() => { + if (!reactions || isEqual(reactions, previousReactions)) { + return; + } + + reactions.forEach(({ timestamp, demuxId, value }) => { + showToast({ + key: `reactions-${timestamp}-${demuxId}`, + onlyShowOnce: true, + autoClose: true, + content: ( + + + {demuxId === localDemuxId + ? i18n('icu:CallingReactions--me') + : conversationsByDemuxId.get(demuxId)?.title} + + ), + }); + }); + }, [ + reactions, + previousReactions, + showToast, + conversationsByDemuxId, + localDemuxId, + i18n, + ]); +} + +function CallingReactionsToastsContainer( + props: CallingReactionsToastsType +): JSX.Element { + const { i18n } = props; + const toastRegionRef = useRef(null); + return ( + +
+ + + ); +} + +function CallingReactionsToasts(props: CallingReactionsToastsType) { + useReactionsToast(props); + return null; +} + +function isHandRaised( + raisedHands: Set | undefined, + demuxId: number | undefined +): boolean { + if (raisedHands === undefined || demuxId === undefined) { + return false; + } + + return raisedHands.has(demuxId); +} diff --git a/ts/components/CallingAudioIndicator.stories.tsx b/ts/components/CallingAudioIndicator.stories.tsx index ae0f02ba7a..5090a4eaf3 100644 --- a/ts/components/CallingAudioIndicator.stories.tsx +++ b/ts/components/CallingAudioIndicator.stories.tsx @@ -2,8 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState, useEffect } from 'react'; -import { boolean } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; +import type { Props } from './CallingAudioIndicator'; import { CallingAudioIndicator, SPEAKING_LINGER_MS, @@ -13,9 +13,18 @@ import { useValueAtFixedRate } from '../hooks/useValueAtFixedRate'; export default { title: 'Components/CallingAudioIndicator', -}; + component: CallingAudioIndicator, + argTypes: { + hasAudio: { + control: { type: 'boolean' }, + }, + }, + args: { + hasAudio: true, + }, +} satisfies Meta; -export function Extreme(): JSX.Element { +export function Extreme(args: Props): JSX.Element { const [audioLevel, setAudioLevel] = useState(1); useEffect(() => { @@ -32,14 +41,14 @@ export function Extreme(): JSX.Element { return ( ); } -export function Random(): JSX.Element { +export function Random(args: Props): JSX.Element { const [audioLevel, setAudioLevel] = useState(1); useEffect(() => { @@ -56,7 +65,7 @@ export function Random(): JSX.Element { return ( diff --git a/ts/components/CallingAudioIndicator.tsx b/ts/components/CallingAudioIndicator.tsx index 4a0eb5b193..f3d1266d67 100644 --- a/ts/components/CallingAudioIndicator.tsx +++ b/ts/components/CallingAudioIndicator.tsx @@ -99,15 +99,17 @@ function Bars({ audioLevel }: { audioLevel: number }): ReactElement { ); } +export type Props = Readonly<{ + hasAudio: boolean; + audioLevel: number; + shouldShowSpeaking: boolean; +}>; + export function CallingAudioIndicator({ hasAudio, audioLevel, shouldShowSpeaking, -}: Readonly<{ - hasAudio: boolean; - audioLevel: number; - shouldShowSpeaking: boolean; -}>): ReactElement { +}: Props): ReactElement { if (!hasAudio) { return (
= {}): PropsType => ({ - buttonType: - overrideProps.buttonType || - select('buttonType', CallingButtonType, CallingButtonType.HANG_UP), - i18n, - onClick: action('on-click'), - onMouseEnter: action('on-mouse-enter'), - onMouseLeave: action('on-mouse-leave'), - tooltipDirection: select( - 'tooltipDirection', - TooltipPlacement, - overrideProps.tooltipDirection || TooltipPlacement.Bottom - ), -}); - export default { title: 'Components/CallingButton', -}; + component: CallingButton, + argTypes: { + buttonType: { + control: { type: 'select' }, + options: Object.values(CallingButtonType), + }, + tooltipDirection: { + control: { type: 'select' }, + options: Object.values(TooltipPlacement), + }, + }, + args: { + buttonType: CallingButtonType.RING_ON, + i18n, + onClick: action('on-click'), + onMouseEnter: action('on-mouse-enter'), + onMouseLeave: action('on-mouse-leave'), + tooltipDirection: TooltipPlacement.Bottom, + }, +} satisfies Meta; -export function KitchenSink(): JSX.Element { +export function KitchenSink(args: PropsType): JSX.Element { return ( <> - {Object.keys(CallingButtonType).map(buttonType => ( - + {Object.values(CallingButtonType).map(buttonType => ( + ))} ); } -export function AudioOn(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.AUDIO_ON, - }); - return ; +export function AudioOn(args: PropsType): JSX.Element { + return ; } -export function AudioOff(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.AUDIO_OFF, - }); - return ; +export function AudioOff(args: PropsType): JSX.Element { + return ; } -export function AudioDisabled(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.AUDIO_DISABLED, - }); - return ; +export function AudioDisabled(args: PropsType): JSX.Element { + return ( + + ); } -export function VideoOn(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.VIDEO_ON, - }); - return ; +export function VideoOn(args: PropsType): JSX.Element { + return ; } -export function VideoOff(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.VIDEO_OFF, - }); - return ; +export function VideoOff(args: PropsType): JSX.Element { + return ; } -export function VideoDisabled(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.VIDEO_DISABLED, - }); - return ; +export function VideoDisabled(args: PropsType): JSX.Element { + return ( + + ); } -export function TooltipRight(): JSX.Element { - const props = createProps({ - tooltipDirection: TooltipPlacement.Right, - }); - return ; +export function TooltipRight(args: PropsType): JSX.Element { + return ; } -TooltipRight.story = { - name: 'Tooltip right', -}; - -export function PresentingOn(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.PRESENTING_ON, - }); - return ; +export function PresentingOn(args: PropsType): JSX.Element { + return ( + + ); } -export function PresentingOff(): JSX.Element { - const props = createProps({ - buttonType: CallingButtonType.PRESENTING_OFF, - }); - return ; +export function PresentingOff(args: PropsType): JSX.Element { + return ( + + ); } diff --git a/ts/components/CallingButton.tsx b/ts/components/CallingButton.tsx index 253e4a65d7..3ea68d4354 100644 --- a/ts/components/CallingButton.tsx +++ b/ts/components/CallingButton.tsx @@ -13,7 +13,6 @@ export enum CallingButtonType { AUDIO_DISABLED = 'AUDIO_DISABLED', AUDIO_OFF = 'AUDIO_OFF', AUDIO_ON = 'AUDIO_ON', - HANG_UP = 'HANG_UP', PRESENTING_DISABLED = 'PRESENTING_DISABLED', PRESENTING_OFF = 'PRESENTING_OFF', PRESENTING_ON = 'PRESENTING_ON', @@ -23,6 +22,7 @@ export enum CallingButtonType { VIDEO_DISABLED = 'VIDEO_DISABLED', VIDEO_OFF = 'VIDEO_OFF', VIDEO_ON = 'VIDEO_ON', + MORE_OPTIONS = 'MORE_OPTIONS', } export type PropsType = { @@ -48,88 +48,72 @@ export function CallingButton({ let classNameSuffix = ''; let tooltipContent = ''; - let label = ''; let disabled = false; if (buttonType === CallingButtonType.AUDIO_DISABLED) { classNameSuffix = 'audio--disabled'; tooltipContent = i18n('icu:calling__button--audio-disabled'); - label = i18n('icu:calling__button--audio__label'); disabled = true; } else if (buttonType === CallingButtonType.AUDIO_OFF) { classNameSuffix = 'audio--off'; tooltipContent = i18n('icu:calling__button--audio-on'); - label = i18n('icu:calling__button--audio__label'); } else if (buttonType === CallingButtonType.AUDIO_ON) { classNameSuffix = 'audio--on'; tooltipContent = i18n('icu:calling__button--audio-off'); - label = i18n('icu:calling__button--audio__label'); } else if (buttonType === CallingButtonType.VIDEO_DISABLED) { classNameSuffix = 'video--disabled'; tooltipContent = i18n('icu:calling__button--video-disabled'); disabled = true; - label = i18n('icu:calling__button--video__label'); } else if (buttonType === CallingButtonType.VIDEO_OFF) { classNameSuffix = 'video--off'; tooltipContent = i18n('icu:calling__button--video-on'); - label = i18n('icu:calling__button--video__label'); } else if (buttonType === CallingButtonType.VIDEO_ON) { classNameSuffix = 'video--on'; tooltipContent = i18n('icu:calling__button--video-off'); - label = i18n('icu:calling__button--video__label'); - } else if (buttonType === CallingButtonType.HANG_UP) { - classNameSuffix = 'hangup'; - tooltipContent = i18n('icu:calling__hangup'); - label = i18n('icu:calling__hangup'); } else if (buttonType === CallingButtonType.RING_DISABLED) { classNameSuffix = 'ring--disabled'; disabled = true; tooltipContent = i18n( 'icu:calling__button--ring__disabled-because-group-is-too-large' ); - label = i18n('icu:calling__button--ring__label'); } else if (buttonType === CallingButtonType.RING_OFF) { classNameSuffix = 'ring--off'; - tooltipContent = i18n('icu:calling__button--ring__on'); - label = i18n('icu:calling__button--ring__label'); + tooltipContent = i18n('icu:CallingButton--ring-on'); } else if (buttonType === CallingButtonType.RING_ON) { classNameSuffix = 'ring--on'; - tooltipContent = i18n('icu:calling__button--ring__off'); - label = i18n('icu:calling__button--ring__label'); + tooltipContent = i18n('icu:CallingButton__ring-off'); } else if (buttonType === CallingButtonType.PRESENTING_DISABLED) { classNameSuffix = 'presenting--disabled'; tooltipContent = i18n('icu:calling__button--presenting-disabled'); disabled = true; - label = i18n('icu:calling__button--presenting__label'); } else if (buttonType === CallingButtonType.PRESENTING_ON) { classNameSuffix = 'presenting--on'; tooltipContent = i18n('icu:calling__button--presenting-off'); - label = i18n('icu:calling__button--presenting__label'); } else if (buttonType === CallingButtonType.PRESENTING_OFF) { classNameSuffix = 'presenting--off'; tooltipContent = i18n('icu:calling__button--presenting-on'); - label = i18n('icu:calling__button--presenting__label'); + } else if (buttonType === CallingButtonType.MORE_OPTIONS) { + classNameSuffix = 'more-options'; + tooltipContent = i18n('icu:CallingButton--more-options'); } - const className = classNames( - 'CallingButton__icon', - `CallingButton__icon--${classNameSuffix}` - ); - return ( - -
+ - -
-
+ +
); } diff --git a/ts/components/CallingDeviceSelection.stories.tsx b/ts/components/CallingDeviceSelection.stories.tsx index 0c2935c389..c75828e1c6 100644 --- a/ts/components/CallingDeviceSelection.stories.tsx +++ b/ts/components/CallingDeviceSelection.stories.tsx @@ -4,6 +4,7 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { Props } from './CallingDeviceSelection'; import { CallingDeviceSelection } from './CallingDeviceSelection'; import { setupI18n } from '../util/setupI18n'; @@ -39,7 +40,7 @@ const createProps = ({ export default { title: 'Components/CallingDeviceSelection', -}; +} satisfies Meta; export function Default(): JSX.Element { return ; diff --git a/ts/components/CallingHeader.stories.tsx b/ts/components/CallingHeader.stories.tsx index e00400db2a..ee377143e5 100644 --- a/ts/components/CallingHeader.stories.tsx +++ b/ts/components/CallingHeader.stories.tsx @@ -2,106 +2,43 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { boolean, number } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './CallingHeader'; import { CallingHeader } from './CallingHeader'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; +import { CallViewMode } from '../types/Calling'; const i18n = setupI18n('en', enMessages); -const createProps = (overrideProps: Partial = {}): PropsType => ({ - i18n, - isGroupCall: boolean('isGroupCall', Boolean(overrideProps.isGroupCall)), - message: overrideProps.message, - participantCount: number( - 'participantCount', - overrideProps.participantCount || 0 - ), - showParticipantsList: boolean( - 'showParticipantsList', - Boolean(overrideProps.showParticipantsList) - ), - title: overrideProps.title || 'With Someone', - toggleParticipants: () => action('toggle-participants'), - togglePip: () => action('toggle-pip'), - toggleSettings: () => action('toggle-settings'), -}); - export default { title: 'Components/CallingHeader', -}; + component: CallingHeader, + argTypes: { + isGroupCall: { control: { type: 'boolean' } }, + participantCount: { control: { type: 'number' } }, + }, + args: { + i18n, + isGroupCall: false, + participantCount: 0, + togglePip: action('toggle-pip'), + callViewMode: CallViewMode.Paginated, + changeCallView: action('change-call-view'), + }, +} satisfies Meta; -export function Default(): JSX.Element { - return ; +export function Default(args: PropsType): JSX.Element { + return ; } -export function LobbyStyle(): JSX.Element { +export function LobbyStyle(args: PropsType): JSX.Element { return ( ); } - -LobbyStyle.story = { - name: 'Lobby style', -}; - -export function WithParticipants(): JSX.Element { - return ( - - ); -} - -export function WithParticipantsShown(): JSX.Element { - return ( - - ); -} - -WithParticipantsShown.story = { - name: 'With Participants (shown)', -}; - -export function LongTitle(): JSX.Element { - return ( - - ); -} - -export function TitleWithMessage(): JSX.Element { - return ( - - ); -} - -TitleWithMessage.story = { - name: 'Title with message', -}; diff --git a/ts/components/CallingHeader.tsx b/ts/components/CallingHeader.tsx index 99081b09d0..920cd8ba3d 100644 --- a/ts/components/CallingHeader.tsx +++ b/ts/components/CallingHeader.tsx @@ -1,145 +1,156 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { ReactNode } from 'react'; -import React from 'react'; import classNames from 'classnames'; +import React from 'react'; import type { LocalizerType } from '../types/Util'; +import { CallViewMode } from '../types/Calling'; import { Tooltip } from './Tooltip'; import { Theme } from '../util/theme'; +import { ContextMenu } from './ContextMenu'; export type PropsType = { + callViewMode?: CallViewMode; i18n: LocalizerType; - isInSpeakerView?: boolean; isGroupCall?: boolean; - message?: ReactNode; onCancel?: () => void; participantCount: number; - showParticipantsList: boolean; - title?: string; - toggleParticipants?: () => void; togglePip?: () => void; toggleSettings: () => void; - toggleSpeakerView?: () => void; + changeCallView?: (mode: CallViewMode) => void; }; export function CallingHeader({ + callViewMode, + changeCallView, i18n, - isInSpeakerView, isGroupCall = false, - message, onCancel, participantCount, - showParticipantsList, - title, - toggleParticipants, togglePip, toggleSettings, - toggleSpeakerView, }: PropsType): JSX.Element { return ( -
- {title ? ( -
{title}
- ) : null} - {message ? ( -
{message}
- ) : null} -
- {isGroupCall && participantCount ? ( +
+ {isGroupCall && + participantCount > 2 && + callViewMode && + changeCallView && (
- changeCallView(CallViewMode.Paginated), + value: CallViewMode.Paginated, + }, + { + icon: 'CallSettingsButton__Icon--OverflowView', + label: i18n('icu:calling__view_mode--overflow'), + onClick: () => changeCallView(CallViewMode.Overflow), + value: CallViewMode.Overflow, + }, + { + icon: 'CallSettingsButton__Icon--SpeakerView', + label: i18n('icu:calling__view_mode--speaker'), + onClick: () => changeCallView(CallViewMode.Speaker), + value: CallViewMode.Speaker, + }, + ]} theme={Theme.Dark} + popperOptions={{ + placement: 'bottom', + strategy: 'absolute', + }} + value={ + // If it's Presentation we want to still show Speaker as selected + callViewMode === CallViewMode.Presentation + ? CallViewMode.Speaker + : callViewMode + } > - - +
+ +
+ +
- ) : null} + )} +
+ + + +
+ {togglePip && (
- {isGroupCall && participantCount > 2 && toggleSpeakerView && ( -
- + +
- )} - {togglePip && ( -
- -
- )} - {onCancel && ( -
- -
- )} -
+ + + +
+ )}
); } + +const CALL_VIEW_MODE_ICON_CLASSNAMES: Record = { + [CallViewMode.Overflow]: 'CallSettingsButton__Icon--OverflowView', + [CallViewMode.Paginated]: 'CallSettingsButton__Icon--PaginatedView', + [CallViewMode.Speaker]: 'CallSettingsButton__Icon--SpeakerView', + [CallViewMode.Presentation]: 'CallSettingsButton__Icon--SpeakerView', +}; +export function getCallViewIconClassname(viewMode: CallViewMode): string { + return CALL_VIEW_MODE_ICON_CLASSNAMES[viewMode]; +} diff --git a/ts/components/CallingLobby.stories.tsx b/ts/components/CallingLobby.stories.tsx index 46d2f73a32..e8e70d25e7 100644 --- a/ts/components/CallingLobby.stories.tsx +++ b/ts/components/CallingLobby.stories.tsx @@ -3,20 +3,22 @@ import * as React from 'react'; import { times } from 'lodash'; -import { boolean } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; +import { v4 as generateUuid } from 'uuid'; +import type { Meta } from '@storybook/react'; import { AvatarColors } from '../types/Colors'; import type { ConversationType } from '../state/ducks/conversations'; import type { PropsType } from './CallingLobby'; -import { CallingLobby } from './CallingLobby'; +import { CallingLobby as UnwrappedCallingLobby } from './CallingLobby'; import { setupI18n } from '../util/setupI18n'; -import { UUID } from '../types/UUID'; +import { generateAci } from '../types/ServiceId'; import enMessages from '../../_locales/en/messages.json'; import { getDefaultConversation, - getDefaultConversationWithUuid, + getDefaultConversationWithServiceId, } from '../test-both/helpers/getDefaultConversation'; +import { CallingToastProvider } from './CallingToast'; const i18n = setupI18n('en', enMessages); @@ -31,10 +33,7 @@ const camera = { }; const createProps = (overrideProps: Partial = {}): PropsType => { - const isGroupCall = boolean( - 'isGroupCall', - overrideProps.isGroupCall || false - ); + const isGroupCall = overrideProps.isGroupCall ?? false; const conversation = isGroupCall ? getDefaultConversation({ title: 'Tahoe Trip', @@ -48,51 +47,52 @@ const createProps = (overrideProps: Partial = {}): PropsType => { groupMembers: overrideProps.groupMembers || (isGroupCall ? times(3, () => getDefaultConversation()) : undefined), - hasLocalAudio: boolean( - 'hasLocalAudio', - overrideProps.hasLocalAudio ?? true - ), - hasLocalVideo: boolean( - 'hasLocalVideo', - overrideProps.hasLocalVideo ?? false - ), + hasLocalAudio: overrideProps.hasLocalAudio ?? true, + hasLocalVideo: overrideProps.hasLocalVideo ?? false, i18n, isGroupCall, isGroupCallOutboundRingEnabled: true, isConversationTooBigToRing: false, - isCallFull: boolean('isCallFull', overrideProps.isCallFull || false), + isCallFull: overrideProps.isCallFull ?? false, me: overrideProps.me || getDefaultConversation({ color: AvatarColors[0], - id: UUID.generate().toString(), - uuid: UUID.generate().toString(), + id: generateUuid(), + serviceId: generateAci(), }), onCallCanceled: action('on-call-canceled'), onJoinCall: action('on-join-call'), - outgoingRing: boolean('outgoingRing', Boolean(overrideProps.outgoingRing)), + outgoingRing: overrideProps.outgoingRing ?? false, peekedParticipants: overrideProps.peekedParticipants || [], setLocalAudio: action('set-local-audio'), setLocalPreview: action('set-local-preview'), setLocalVideo: action('set-local-video'), setOutgoingRing: action('set-outgoing-ring'), - showParticipantsList: boolean( - 'showParticipantsList', - Boolean(overrideProps.showParticipantsList) - ), + showParticipantsList: overrideProps.showParticipantsList ?? false, toggleParticipants: action('toggle-participants'), toggleSettings: action('toggle-settings'), }; }; +function CallingLobby(props: ReturnType) { + return ( + + + + ); +} + const fakePeekedParticipant = (conversationProps: Partial) => - getDefaultConversationWithUuid({ + getDefaultConversationWithServiceId({ ...conversationProps, }); export default { title: 'Components/CallingLobby', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function Default(): JSX.Element { const props = createProps(); @@ -106,27 +106,19 @@ export function NoCameraNoAvatar(): JSX.Element { return ; } -NoCameraNoAvatar.story = { - name: 'No Camera, no avatar', -}; - export function NoCameraLocalAvatar(): JSX.Element { const props = createProps({ availableCameras: [], me: getDefaultConversation({ avatarPath: '/fixtures/kitten-4-112-112.jpg', color: AvatarColors[0], - id: UUID.generate().toString(), - uuid: UUID.generate().toString(), + id: generateUuid(), + serviceId: generateAci(), }), }); return ; } -NoCameraLocalAvatar.story = { - name: 'No Camera, local avatar', -}; - export function LocalVideo(): JSX.Element { const props = createProps({ hasLocalVideo: true, @@ -141,20 +133,12 @@ export function InitiallyMuted(): JSX.Element { return ; } -InitiallyMuted.story = { - name: 'Initially muted', -}; - -export function GroupCall0PeekedParticipants(): JSX.Element { +export function GroupCallWithNoPeekedParticipants(): JSX.Element { const props = createProps({ isGroupCall: true, peekedParticipants: [] }); return ; } -GroupCall0PeekedParticipants.story = { - name: 'Group Call - 0 peeked participants', -}; - -export function GroupCall1PeekedParticipant(): JSX.Element { +export function GroupCallWith1PeekedParticipant(): JSX.Element { const props = createProps({ isGroupCall: true, peekedParticipants: [{ title: 'Sam' }].map(fakePeekedParticipant), @@ -162,28 +146,20 @@ export function GroupCall1PeekedParticipant(): JSX.Element { return ; } -GroupCall1PeekedParticipant.story = { - name: 'Group Call - 1 peeked participant', -}; - -export function GroupCall1PeekedParticipantSelf(): JSX.Element { - const uuid = UUID.generate().toString(); +export function GroupCallWith1PeekedParticipantSelf(): JSX.Element { + const serviceId = generateAci(); const props = createProps({ isGroupCall: true, me: getDefaultConversation({ - id: UUID.generate().toString(), - uuid, + id: generateUuid(), + serviceId, }), - peekedParticipants: [fakePeekedParticipant({ title: 'Ash', uuid })], + peekedParticipants: [fakePeekedParticipant({ title: 'Ash', serviceId })], }); return ; } -GroupCall1PeekedParticipantSelf.story = { - name: 'Group Call - 1 peeked participant (self)', -}; - -export function GroupCall4PeekedParticipants(): JSX.Element { +export function GroupCallWith4PeekedParticipants(): JSX.Element { const props = createProps({ isGroupCall: true, peekedParticipants: ['Sam', 'Cayce', 'April', 'Logan', 'Carl'].map(title => @@ -193,11 +169,7 @@ export function GroupCall4PeekedParticipants(): JSX.Element { return ; } -GroupCall4PeekedParticipants.story = { - name: 'Group Call - 4 peeked participants', -}; - -export function GroupCall4PeekedParticipantsParticipantsList(): JSX.Element { +export function GroupCallWith4PeekedParticipantsParticipantsList(): JSX.Element { const props = createProps({ isGroupCall: true, peekedParticipants: ['Sam', 'Cayce', 'April', 'Logan', 'Carl'].map(title => @@ -208,11 +180,7 @@ export function GroupCall4PeekedParticipantsParticipantsList(): JSX.Element { return ; } -GroupCall4PeekedParticipantsParticipantsList.story = { - name: 'Group Call - 4 peeked participants (participants list)', -}; - -export function GroupCallCallFull(): JSX.Element { +export function GroupCallWithCallFull(): JSX.Element { const props = createProps({ isGroupCall: true, isCallFull: true, @@ -223,18 +191,10 @@ export function GroupCallCallFull(): JSX.Element { return ; } -GroupCallCallFull.story = { - name: 'Group Call - call full', -}; - -export function GroupCall0PeekedParticipantsBigGroup(): JSX.Element { +export function GroupCallWith0PeekedParticipantsBigGroup(): JSX.Element { const props = createProps({ isGroupCall: true, groupMembers: times(100, () => getDefaultConversation()), }); return ; } - -GroupCall0PeekedParticipantsBigGroup.story = { - name: 'Group Call - 0 peeked participants, big group', -}; diff --git a/ts/components/CallingLobby.tsx b/ts/components/CallingLobby.tsx index 9b4f9b068f..2b047fc617 100644 --- a/ts/components/CallingLobby.tsx +++ b/ts/components/CallingLobby.tsx @@ -12,8 +12,8 @@ import type { import { CallingButton, CallingButtonType } from './CallingButton'; import { TooltipPlacement } from './Tooltip'; import { CallBackgroundBlur } from './CallBackgroundBlur'; +import { CallParticipantCount } from './CallParticipantCount'; import { CallingHeader } from './CallingHeader'; -import { CallingToast, DEFAULT_LIFETIME } from './CallingToast'; import { CallingPreCallInfo, RingMode } from './CallingPreCallInfo'; import { CallingLobbyJoinButton, @@ -23,6 +23,8 @@ import type { LocalizerType } from '../types/Util'; import { useIsOnline } from '../hooks/useIsOnline'; import * as KeyboardLayout from '../services/keyboardLayout'; import type { ConversationType } from '../state/ducks/conversations'; +import { useCallingToasts } from './CallingToast'; +import { CallingButtonToastsContainer } from './CallingToastManager'; export type PropsType = { availableCameras: Array; @@ -49,7 +51,9 @@ export type PropsType = { isGroupCall: boolean; isGroupCallOutboundRingEnabled: boolean; isCallFull?: boolean; - me: Readonly>; + me: Readonly< + Pick + >; onCallCanceled: () => void; onJoinCall: () => void; outgoingRing: boolean; @@ -82,26 +86,10 @@ export function CallingLobby({ setLocalPreview, setLocalVideo, setOutgoingRing, - showParticipantsList, toggleParticipants, toggleSettings, outgoingRing, }: PropsType): JSX.Element { - const [isMutedToastVisible, setIsMutedToastVisible] = React.useState( - !hasLocalAudio - ); - React.useEffect(() => { - if (!isMutedToastVisible) { - return; - } - const timeout = setTimeout(() => { - setIsMutedToastVisible(false); - }, DEFAULT_LIFETIME); - return () => { - clearTimeout(timeout); - }; - }, [isMutedToastVisible]); - const localVideoRef = React.useRef(null); const shouldShowLocalVideo = hasLocalVideo && availableCameras.length > 0; @@ -212,9 +200,39 @@ export function CallingLobby({ callingLobbyJoinButtonVariant = CallingLobbyJoinButtonVariant.Start; } + const callStatus = React.useMemo(() => { + if (isGroupCall) { + return ( + + ); + } + if (hasLocalVideo) { + return i18n('icu:ContactListItem__menu__video-call'); + } + if (hasLocalAudio) { + return i18n('icu:CallControls__InfoDisplay--audio-call'); + } + return null; + }, [ + isGroupCall, + peekedParticipants.length, + i18n, + hasLocalVideo, + hasLocalAudio, + groupMembers?.length, + toggleParticipants, + ]); + + useWasInitiallyMutedToast(hasLocalAudio, i18n); + return ( -
+
{shouldShowLocalVideo ? (
-
- - - +
+
+
+
+
+ {conversation.title} +
+
{callStatus}
+
+ +
+ + + +
+
+ { + setIsCallConnecting(true); + onJoinCall(); + }} + variant={callingLobbyJoinButtonVariant} + /> +
+
+
- - { - setIsCallConnecting(true); - onJoinCall(); - }} - variant={callingLobbyJoinButtonVariant} - />
); } + +function useWasInitiallyMutedToast( + hasLocalAudio: boolean, + i18n: LocalizerType +) { + const [wasInitiallyMuted] = React.useState(!hasLocalAudio); + const { showToast, hideToast } = useCallingToasts(); + const INITIALLY_MUTED_KEY = 'initially-muted-group-size'; + React.useEffect(() => { + if (wasInitiallyMuted) { + showToast({ + key: INITIALLY_MUTED_KEY, + content: i18n( + 'icu:calling__lobby-automatically-muted-because-there-are-a-lot-of-people' + ), + autoClose: true, + dismissable: true, + onlyShowOnce: true, + }); + } + }, [wasInitiallyMuted, i18n, showToast]); + + // Hide this toast if the user unmutes + React.useEffect(() => { + if (wasInitiallyMuted && hasLocalAudio) { + hideToast(INITIALLY_MUTED_KEY); + } + }, [hideToast, wasInitiallyMuted, hasLocalAudio]); +} diff --git a/ts/components/CallingLobbyJoinButton.tsx b/ts/components/CallingLobbyJoinButton.tsx index c016655891..1dad068178 100644 --- a/ts/components/CallingLobbyJoinButton.tsx +++ b/ts/components/CallingLobbyJoinButton.tsx @@ -9,9 +9,6 @@ import type { LocalizerType } from '../types/Util'; import { Button, ButtonVariant } from './Button'; import { Spinner } from './Spinner'; -const PADDING_HORIZONTAL = 48; -const PADDING_VERTICAL = 12; - export enum CallingLobbyJoinButtonVariant { CallIsFull = 'CallIsFull', Join = 'Join', @@ -47,18 +44,24 @@ export function CallingLobbyJoinButton({ const childrenByVariant: Record = { [CallingLobbyJoinButtonVariant.CallIsFull]: i18n( - 'icu:calling__call-is-full' + 'icu:CallingLobbyJoinButton--call-full' + ), + [CallingLobbyJoinButtonVariant.Loading]: ( + + ), + [CallingLobbyJoinButtonVariant.Join]: i18n( + 'icu:CallingLobbyJoinButton--join' + ), + [CallingLobbyJoinButtonVariant.Start]: i18n( + 'icu:CallingLobbyJoinButton--start' ), - [CallingLobbyJoinButtonVariant.Loading]: , - [CallingLobbyJoinButtonVariant.Join]: i18n('icu:calling__join'), - [CallingLobbyJoinButtonVariant.Start]: i18n('icu:calling__start'), }; return ( <> {Boolean(width && height) && (
@@ -173,6 +175,7 @@ export function CallingPipRemoteVideo({ remoteParticipant={activeGroupCallSpeaker} remoteParticipantsCount={activeCall.remoteParticipants.length} isActiveSpeakerInSpeakerView={false} + isCallReconnecting={isReconnecting(activeCall)} />
); diff --git a/ts/components/CallingPreCallInfo.stories.tsx b/ts/components/CallingPreCallInfo.stories.tsx index 4297403e6b..c20e0d8940 100644 --- a/ts/components/CallingPreCallInfo.stories.tsx +++ b/ts/components/CallingPreCallInfo.stories.tsx @@ -3,10 +3,11 @@ import React from 'react'; import { times } from 'lodash'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; - +import type { PropsType } from './CallingPreCallInfo'; import { CallingPreCallInfo, RingMode } from './CallingPreCallInfo'; const i18n = setupI18n('en', enMessages); @@ -22,7 +23,7 @@ const otherMembers = times(6, () => getDefaultConversation()); export default { title: 'Components/CallingPreCallInfo', -}; +} satisfies Meta; export function DirectConversation(): JSX.Element { return ( @@ -35,10 +36,6 @@ export function DirectConversation(): JSX.Element { ); } -DirectConversation.story = { - name: 'Direct conversation', -}; - export function Ring0(): JSX.Element { return ( ); } - -GroupConversationCallIsFull.story = { - name: 'Group conversation, call is full', -}; diff --git a/ts/components/CallingPreCallInfo.tsx b/ts/components/CallingPreCallInfo.tsx index 1dff078197..ca0958cf79 100644 --- a/ts/components/CallingPreCallInfo.tsx +++ b/ts/components/CallingPreCallInfo.tsx @@ -15,7 +15,7 @@ export enum RingMode { IsRinging, } -type PropsType = { +export type PropsType = { conversation: Pick< ConversationType, | 'acceptedMessageRequest' @@ -30,14 +30,14 @@ type PropsType = { | 'unblurredAvatarPath' >; i18n: LocalizerType; - me: Pick; + me: Pick; ringMode: RingMode; // The following should only be set for group conversations. groupMembers?: Array>; isCallFull?: boolean; peekedParticipants?: Array< - Pick + Pick >; }; @@ -61,7 +61,7 @@ export function CallingPreCallInfo({ // device. let hasYou = false; const participantNames = peekedParticipants.map(participant => { - if (participant.uuid === me.uuid) { + if (participant.serviceId === me.serviceId) { hasYou = true; return i18n('icu:you'); } @@ -184,7 +184,7 @@ export function CallingPreCallInfo({ phoneNumber={conversation.phoneNumber} profileName={conversation.profileName} sharedGroupNames={conversation.sharedGroupNames} - size={AvatarSize.EIGHTY} + size={AvatarSize.NINETY_SIX} title={conversation.title} unblurredAvatarPath={conversation.unblurredAvatarPath} i18n={i18n} diff --git a/ts/components/CallingRaisedHandsList.stories.tsx b/ts/components/CallingRaisedHandsList.stories.tsx new file mode 100644 index 0000000000..06807147a4 --- /dev/null +++ b/ts/components/CallingRaisedHandsList.stories.tsx @@ -0,0 +1,97 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import * as React from 'react'; +import { times } from 'lodash'; +import { action } from '@storybook/addon-actions'; + +import type { Meta } from '@storybook/react'; +import type { PropsType } from './CallingRaisedHandsList'; +import { CallingRaisedHandsList } from './CallingRaisedHandsList'; +import type { ConversationType } from '../state/ducks/conversations'; +import { AvatarColors } from '../types/Colors'; +import { getDefaultConversationWithServiceId } from '../test-both/helpers/getDefaultConversation'; +import { setupI18n } from '../util/setupI18n'; +import enMessages from '../../_locales/en/messages.json'; + +const MAX_HANDS = 20; +const LOCAL_DEMUX_ID = 1; +const NAMES = [ + 'Tom Ato', + 'Ann Chovy', + 'Longanisa Lisa Duchess of Summer Pumpkin', + 'Rick Astley', + 'Ash Ketchup', + 'Kiki', +]; + +const i18n = setupI18n('en', enMessages); + +const conversation = getDefaultConversationWithServiceId({ + id: '3051234567', + avatarPath: undefined, + color: AvatarColors[0], + title: 'Rick Sanchez', + name: 'Rick Sanchez', + phoneNumber: '3051234567', + profileName: 'Rick Sanchez', +}); + +const conversationsByDemuxId = new Map( + times(MAX_HANDS).map(index => [ + LOCAL_DEMUX_ID + index + 1, + getDefaultConversationWithServiceId({ + title: NAMES[index] || `Participant ${index + 1}`, + }), + ]) +); +conversationsByDemuxId.set(LOCAL_DEMUX_ID, conversation); + +const createProps = (overrideProps: Partial = {}): PropsType => ({ + i18n, + onClose: action('on-close'), + onLowerMyHand: action('on-lower-my-hand'), + localDemuxId: LOCAL_DEMUX_ID, + conversationsByDemuxId, + localHandRaised: overrideProps.localHandRaised || false, + raisedHands: overrideProps.raisedHands || new Set(), +}); + +export default { + title: 'Components/CallingRaisedHandsList', +} satisfies Meta; + +export function Me(): JSX.Element { + const props = createProps({ + localHandRaised: true, + raisedHands: new Set([LOCAL_DEMUX_ID]), + }); + return ; +} + +export function MeOnAnotherDevice(): JSX.Element { + const props = createProps({ + raisedHands: new Set([LOCAL_DEMUX_ID]), + }); + return ; +} + +export function MeAndOne(): JSX.Element { + const props = createProps({ + localHandRaised: true, + raisedHands: new Set([LOCAL_DEMUX_ID, LOCAL_DEMUX_ID + 1]), + }); + return ; +} + +export function One(): JSX.Element { + const props = createProps({ raisedHands: new Set([LOCAL_DEMUX_ID + 1]) }); + return ; +} + +export function Many(): JSX.Element { + const props = createProps({ + raisedHands: new Set([...conversationsByDemuxId.keys()]), + }); + return ; +} diff --git a/ts/components/CallingRaisedHandsList.tsx b/ts/components/CallingRaisedHandsList.tsx new file mode 100644 index 0000000000..d5eb7b0ed5 --- /dev/null +++ b/ts/components/CallingRaisedHandsList.tsx @@ -0,0 +1,137 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import React from 'react'; + +import { Avatar, AvatarSize } from './Avatar'; +import { ContactName } from './conversation/ContactName'; +import type { ConversationsByDemuxIdType } from '../types/Calling'; +import type { ServiceIdString } from '../types/ServiceId'; +import type { LocalizerType } from '../types/Util'; +import type { ConversationType } from '../state/ducks/conversations'; +import { ModalHost } from './ModalHost'; +import * as log from '../logging/log'; + +export type PropsType = { + readonly i18n: LocalizerType; + readonly onClose: () => void; + readonly onLowerMyHand: () => void; + readonly localDemuxId: number | undefined; + readonly conversationsByDemuxId: ConversationsByDemuxIdType; + readonly raisedHands: Set; + readonly localHandRaised: boolean; +}; + +export function CallingRaisedHandsList({ + i18n, + onClose, + onLowerMyHand, + localDemuxId, + conversationsByDemuxId, + raisedHands, + localHandRaised, +}: PropsType): JSX.Element | null { + const ourServiceId: ServiceIdString | undefined = localDemuxId + ? conversationsByDemuxId.get(localDemuxId)?.serviceId + : undefined; + + const participants = React.useMemo>(() => { + const serviceIds: Set = new Set(); + const conversations: Array = []; + raisedHands.forEach(demuxId => { + const conversation = conversationsByDemuxId.get(demuxId); + if (!conversation) { + log.warn( + 'CallingRaisedHandsList: Failed to get conversationsByDemuxId for demuxId', + { demuxId } + ); + return; + } + + const { serviceId } = conversation; + if (serviceId) { + if (serviceIds.has(serviceId)) { + return; + } + + serviceIds.add(serviceId); + } + + conversations.push(conversation); + }); + return conversations; + }, [raisedHands, conversationsByDemuxId]); + + return ( + +
+
+
+ {i18n('icu:CallingRaisedHandsList__Title', { + count: participants.length, + })} +
+
+
    + {participants.map((participant: ConversationType, index: number) => ( +
  • +
    + + {ourServiceId && participant.serviceId === ourServiceId ? ( + + {i18n('icu:you')} + + ) : ( + + )} +
    +
    + {localHandRaised && + ourServiceId && + participant.serviceId === ourServiceId && ( + + )} +
    +
    +
  • + ))} +
+
+
+ ); +} diff --git a/ts/components/CallingScreenSharingController.stories.tsx b/ts/components/CallingScreenSharingController.stories.tsx index 76211b4887..08a1c30430 100644 --- a/ts/components/CallingScreenSharingController.stories.tsx +++ b/ts/components/CallingScreenSharingController.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './CallingScreenSharingController'; import { CallingScreenSharingController } from './CallingScreenSharingController'; @@ -21,7 +22,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/CallingScreenSharingController', -}; +} satisfies Meta; export function Controller(): JSX.Element { return ; @@ -37,7 +38,3 @@ export function ReallyLongAppName(): JSX.Element { /> ); } - -ReallyLongAppName.story = { - name: 'Really long app name', -}; diff --git a/ts/components/CallingSelectPresentingSourcesModal.stories.tsx b/ts/components/CallingSelectPresentingSourcesModal.stories.tsx index e48a88539a..ce7332176e 100644 --- a/ts/components/CallingSelectPresentingSourcesModal.stories.tsx +++ b/ts/components/CallingSelectPresentingSourcesModal.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './CallingSelectPresentingSourcesModal'; import { CallingSelectPresentingSourcesModal } from './CallingSelectPresentingSourcesModal'; @@ -55,7 +56,7 @@ const createProps = (): PropsType => ({ export default { title: 'Components/CallingSelectPresentingSourcesModal', -}; +} satisfies Meta; export function Modal(): JSX.Element { return ; diff --git a/ts/components/CallingToast.tsx b/ts/components/CallingToast.tsx index 64ad1bc6f5..22f0c3b388 100644 --- a/ts/components/CallingToast.tsx +++ b/ts/components/CallingToast.tsx @@ -1,32 +1,422 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React from 'react'; +import React, { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useRef, +} from 'react'; +import { useFocusWithin, useHover, mergeProps } from 'react-aria'; +import { createPortal } from 'react-dom'; +import { useTransition, animated } from '@react-spring/web'; import classNames from 'classnames'; +import { v4 as uuid } from 'uuid'; +import { useIsMounted } from '../hooks/useIsMounted'; +import type { LocalizerType } from '../types/I18N'; +import { usePrevious } from '../hooks/usePrevious'; +import { difference } from '../util/setUtil'; -type PropsType = { - isVisible: boolean; - onClick: () => unknown; - children?: JSX.Element | string; +const DEFAULT_LIFETIME = 5000; +const DEFAULT_TRANSITION_FROM = { + opacity: 0, + scale: 0.85, }; -export const DEFAULT_LIFETIME = 5000; +export type CallingToastType = { + // If key is provided, calls to showToast will be idempotent; otherwise an + // auto-generated key will be returned + key?: string; + content: JSX.Element | string; + autoClose: boolean; + dismissable?: boolean; +} & ( + | { + // key must be provided if the toast is 'only-show-once' + key: string; + onlyShowOnce: true; + } + | { + onlyShowOnce?: never; + } +); -export function CallingToast({ - isVisible, - onClick, +type CallingToastStateType = CallingToastType & { + key: string; +}; + +type CallingToastContextType = { + showToast: (toast: CallingToastType) => string; + hideToast: (id: string) => void; +}; + +type TimeoutType = + | { status: 'active'; timeout: NodeJS.Timeout; endAt: number } + | { status: 'paused'; remaining: number }; + +const CallingToastContext = createContext(null); + +export function CallingToastProvider({ + i18n, children, -}: PropsType): JSX.Element { + region, + maxNonPersistentToasts = 5, + lifetime = DEFAULT_LIFETIME, + transitionFrom = DEFAULT_TRANSITION_FROM, +}: { + i18n: LocalizerType; + children: React.ReactNode; + region?: React.RefObject; + maxNonPersistentToasts?: number; + lifetime?: number; + transitionFrom?: object; +}): JSX.Element { + const [toasts, setToasts] = React.useState>([]); + const previousToasts = usePrevious([], toasts); + const timeouts = React.useRef>(new Map()); + // All toasts are paused on hover or focus so that toasts don't disappear while a user + // is attempting to interact with them + const timeoutsStatus = React.useRef<'active' | 'paused'>('active'); + const shownToasts = React.useRef>(new Set()); + const isMounted = useIsMounted(); + + const clearToastTimeout = useCallback((key: string) => { + const timeout = timeouts.current.get(key); + if (timeout?.status === 'active') { + clearTimeout(timeout.timeout); + } + timeouts.current.delete(key); + }, []); + + const hideToast = useCallback( + (key: string) => { + if (!isMounted()) { + return; + } + + clearToastTimeout(key); + + setToasts(state => { + const existingIndex = state.findIndex(toast => toast.key === key); + if (existingIndex === -1) { + // Important to return the same state object here to avoid infinite recursion if + // hideToast is in a useEffect dependency array + return state; + } + return [ + ...state.slice(0, existingIndex), + ...state.slice(existingIndex + 1), + ]; + }); + }, + [isMounted, clearToastTimeout] + ); + + const startTimer = useCallback( + (key: string, duration: number) => { + if (timeoutsStatus.current === 'paused') { + timeouts.current.set(key, { status: 'paused', remaining: duration }); + } else { + timeouts.current.set(key, { + timeout: setTimeout(() => hideToast(key), duration), + status: 'active', + endAt: Date.now() + duration, + }); + } + }, + [hideToast] + ); + + const showToast = useCallback( + (toast: CallingToastType): string => { + if (toast.onlyShowOnce && shownToasts.current.has(toast.key)) { + return toast.key; + } + + const key = toast.key ?? uuid(); + + setToasts(state => { + const isCurrentlyBeingShown = state.some( + existingToast => toast.key === existingToast.key + ); + + if (isCurrentlyBeingShown) { + return state; + } + + const persistentToasts = state.filter(({ autoClose }) => !autoClose); + const nonPersistentToasts = state.filter(({ autoClose }) => autoClose); + + if ( + nonPersistentToasts.length === maxNonPersistentToasts && + maxNonPersistentToasts > 0 + ) { + const toastToBePushedOut = nonPersistentToasts.pop(); + + if (toastToBePushedOut) { + clearToastTimeout(toastToBePushedOut.key); + } + } + + if (toast.autoClose) { + startTimer(key, lifetime); + nonPersistentToasts.unshift({ ...toast, key }); + } else { + persistentToasts.unshift({ ...toast, key }); + } + shownToasts.current.add(key); + + // Show persistent toasts at top of list always + return [...persistentToasts, ...nonPersistentToasts]; + }); + + return key; + }, + [startTimer, clearToastTimeout, maxNonPersistentToasts, lifetime] + ); + + const pauseAll = useCallback(() => { + const now = Date.now(); + timeoutsStatus.current = 'paused'; + + for (const [key, timeout] of [...timeouts.current.entries()]) { + if (!timeout || timeout.status !== 'active') { + return; + } + clearTimeout(timeout.timeout); + + timeouts.current.set(key, { + status: 'paused', + remaining: timeout.endAt - now, + }); + } + }, []); + + const resumeAll = useCallback(() => { + timeoutsStatus.current = 'active'; + + for (const [key, timeout] of [...timeouts.current.entries()]) { + if (!timeout || timeout.status !== 'paused') { + return; + } + + startTimer(key, timeout.remaining); + } + }, [startTimer]); + + const { hoverProps } = useHover({ + onHoverStart: () => pauseAll(), + onHoverEnd: () => resumeAll(), + }); + const { focusWithinProps } = useFocusWithin({ + onFocusWithin: () => pauseAll(), + onBlurWithin: () => resumeAll(), + }); + + const TOAST_HEIGHT_PX = 42; + const TOAST_GAP_PX = 8; + + const curToasts = new Set(toasts); + const prevToasts = new Set(previousToasts); + + const toastsRemoved = difference(prevToasts, curToasts); + const toastsAdded = difference(curToasts, prevToasts); + + const transitions = useTransition(toasts, { + from: item => { + const enteringItemIndex = toasts.findIndex( + toast => toast.key === item.key + ); + const isToastReplacingAnExistingOneAtThisPosition = toastsRemoved.has( + previousToasts[enteringItemIndex] + ); + return { + ...transitionFrom, + zIndex: item.autoClose ? 1 : 2, + marginTop: + // If this toast is replacing an existing one, don't slide-down, just fade-in + // Note: this just refers to toasts added / removed within one render cycle; + // this will almost always be when replacing toasts that are related + // Note: this + // Example: + // previous current + // "Muted" "Unmuted" + // + // The previous toast should disappear and the new one should fade-in in its + // place, so it looks like a replacement. + isToastReplacingAnExistingOneAtThisPosition + ? '0px' + : `${-1 * TOAST_HEIGHT_PX}px`, + }; + }, + enter: { + opacity: 1, + scale: 1, + marginTop: '0px', + config: (key: string) => { + if (key === 'marginTop') { + return { + velocity: 0.005, + friction: 30, + }; + } + return {}; + }, + }, + leave: item => { + const leavingItemIndex = previousToasts.findIndex( + toast => toast.key === item.key + ); + const isToastBeingReplacedByANewOneAtThisPosition = toastsAdded.has( + toasts[leavingItemIndex] + ); + return { + zIndex: 0, + opacity: 0, + // If the last toast in the list is leaving, we don't need to move it up. + marginTop: + leavingItemIndex === previousToasts.length - 1 + ? '0px' + : `${-1 * (TOAST_HEIGHT_PX + TOAST_GAP_PX)}px`, + // If this toast is being replaced by a new toast at this position, disappear + // immediately (don't interfere with new one coming in) + display: isToastBeingReplacedByANewOneAtThisPosition ? 'none' : 'block', + config: (key: string) => { + if (key === 'zIndex') { + return { duration: 0 }; + } + if (key === 'display') { + return { duration: 0 }; + } + if (key === 'opacity') { + return { duration: 100 }; + } + return { clamp: true, duration: 200 }; + }, + }; + }, + }); + + const contextValue = useMemo(() => { + return { + showToast, + hideToast, + }; + }, [showToast, hideToast]); + return ( - + ); } + +function CallingToast( + props: CallingToastType & { + onClick?: VoidFunction; + } +): JSX.Element { + const className = classNames( + 'CallingToast', + !props.autoClose && 'CallingToast--persistent', + props.dismissable && 'CallingToast--dismissable' + ); + + const elementHtmlProps: React.HTMLAttributes = { + role: 'alert', + 'aria-live': props.autoClose ? 'assertive' : 'polite', + }; + + if (props.dismissable) { + return ( +
+ +
+ ); + } + return ( +
+ {props.content} +
+ ); +} + +// Preferred way of showing/hiding toasts: useCallingToasts is a helper function which +// will hide all toasts shown when the component from which you are using it unmounts +export function useCallingToasts(): CallingToastContextType { + const callingToastContext = useContext(CallingToastContext); + + if (!callingToastContext) { + throw new Error('Calling Toasts must be wrapped in CallingToastProvider'); + } + const toastsShown = useRef>(new Set()); + + const wrappedShowToast = useCallback( + (toast: CallingToastType) => { + const key = callingToastContext.showToast(toast); + toastsShown.current.add(key); + return key; + }, + [callingToastContext] + ); + + const hideAllShownToasts = useCallback(() => { + [...toastsShown.current].forEach(callingToastContext.hideToast); + }, [callingToastContext]); + + useEffect(() => { + return hideAllShownToasts; + }, [hideAllShownToasts]); + + return useMemo( + () => ({ + ...callingToastContext, + showToast: wrappedShowToast, + }), + [wrappedShowToast, callingToastContext] + ); +} + +export function PersistentCallingToast({ + children, +}: { + children: string | JSX.Element; +}): null { + const { showToast } = useCallingToasts(); + const toastId = useRef(uuid()); + useEffect(() => { + showToast({ + key: toastId.current, + content: children, + autoClose: false, + }); + }, [children, showToast]); + + return null; +} diff --git a/ts/components/CallingToastManager.tsx b/ts/components/CallingToastManager.tsx index b5069501a2..a1d0e3529e 100644 --- a/ts/components/CallingToastManager.tsx +++ b/ts/components/CallingToastManager.tsx @@ -1,46 +1,31 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useRef } from 'react'; import type { ActiveCallType } from '../types/Calling'; -import { CallMode, GroupCallConnectionState } from '../types/Calling'; +import { CallMode } from '../types/Calling'; import type { ConversationType } from '../state/ducks/conversations'; import type { LocalizerType } from '../types/Util'; -import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary'; -import { CallingToast, DEFAULT_LIFETIME } from './CallingToast'; +import { CallingToastProvider, useCallingToasts } from './CallingToast'; +import { usePrevious } from '../hooks/usePrevious'; +import { + difference as setDifference, + isEqual as setIsEqual, +} from '../util/setUtil'; +import * as log from '../logging/log'; type PropsType = { activeCall: ActiveCallType; i18n: LocalizerType; }; -type ToastType = - | { - message: string; - type: 'dismissable' | 'static'; - } - | undefined; - -function getReconnectingToast({ activeCall, i18n }: PropsType): ToastType { - if ( - activeCall.callMode === CallMode.Group && - activeCall.connectionState === GroupCallConnectionState.Reconnecting - ) { - return { - message: i18n('icu:callReconnecting'), - type: 'static', - }; - } - return undefined; -} - const ME = Symbol('me'); function getCurrentPresenter( activeCall: Readonly -): ConversationType | typeof ME | undefined { +): ConversationType | { id: typeof ME } | undefined { if (activeCall.presentingSource) { - return ME; + return { id: ME }; } if (activeCall.callMode === CallMode.Direct) { const isOtherPersonPresenting = activeCall.remoteParticipants.some( @@ -56,92 +41,230 @@ function getCurrentPresenter( return undefined; } -function useScreenSharingToast({ activeCall, i18n }: PropsType): ToastType { - const [result, setResult] = useState(undefined); +export function useScreenSharingStoppedToast({ + activeCall, + i18n, +}: PropsType): void { + const { showToast, hideToast } = useCallingToasts(); - const [previousPresenter, setPreviousPresenter] = useState< - undefined | { id: string | typeof ME; title?: string } - >(undefined); + const SOMEONE_STOPPED_PRESENTING_TOAST_KEY = 'someone_stopped_presenting'; - const previousPresenterId = previousPresenter?.id; - const previousPresenterTitle = previousPresenter?.title; + const currentPresenter = useMemo( + () => getCurrentPresenter(activeCall), + [activeCall] + ); + const previousPresenter = usePrevious(currentPresenter, currentPresenter); useEffect(() => { - const currentPresenter = getCurrentPresenter(activeCall); - if (!currentPresenter && previousPresenterId) { - if (previousPresenterId === ME) { - setResult({ - type: 'dismissable', - message: i18n('icu:calling__presenting--you-stopped'), - }); - } else if (previousPresenterTitle) { - setResult({ - type: 'dismissable', - message: i18n('icu:calling__presenting--person-stopped', { - name: previousPresenterTitle, - }), - }); - } - } - }, [activeCall, i18n, previousPresenterId, previousPresenterTitle]); - - useEffect(() => { - const currentPresenter = getCurrentPresenter(activeCall); - if (currentPresenter === ME) { - setPreviousPresenter({ - id: ME, + if (previousPresenter && !currentPresenter) { + hideToast(SOMEONE_STOPPED_PRESENTING_TOAST_KEY); + showToast({ + key: SOMEONE_STOPPED_PRESENTING_TOAST_KEY, + content: + previousPresenter.id === ME + ? i18n('icu:calling__presenting--you-stopped') + : i18n('icu:calling__presenting--person-stopped', { + name: previousPresenter.title, + }), + autoClose: true, }); - } else if (!currentPresenter) { - setPreviousPresenter(undefined); - } else { - const { id, title } = currentPresenter; - setPreviousPresenter({ id, title }); } - }, [activeCall]); - - return result; + }, [ + activeCall, + hideToast, + currentPresenter, + previousPresenter, + showToast, + i18n, + ]); } -// In the future, this component should show toasts when users join or leave. See -// DESKTOP-902. -export function CallingToastManager(props: PropsType): JSX.Element { - const reconnectingToast = getReconnectingToast(props); - const screenSharingToast = useScreenSharingToast(props); - - let toast: ToastType; - if (reconnectingToast) { - toast = reconnectingToast; - } else if (screenSharingToast) { - toast = screenSharingToast; - } - - const [isVisible, setIsVisible] = useState(false); - const timeoutRef = useRef(null); - - const dismissToast = useCallback(() => { - if (timeoutRef) { - setIsVisible(false); - } - }, [setIsVisible, timeoutRef]); +function useMutedToast({ + hasLocalAudio, + i18n, +}: { + hasLocalAudio: boolean; + i18n: LocalizerType; +}): void { + const previousHasLocalAudio = usePrevious(hasLocalAudio, hasLocalAudio); + const { showToast, hideToast } = useCallingToasts(); + const MUTED_TOAST_KEY = 'muted'; useEffect(() => { - setIsVisible(toast !== undefined); - }, [toast]); + if ( + previousHasLocalAudio !== undefined && + hasLocalAudio !== previousHasLocalAudio + ) { + hideToast(MUTED_TOAST_KEY); + showToast({ + key: MUTED_TOAST_KEY, + content: hasLocalAudio + ? i18n('icu:CallControls__MutedToast--unmuted') + : i18n('icu:CallControls__MutedToast--muted'), + autoClose: true, + dismissable: true, + }); + } + }, [hasLocalAudio, previousHasLocalAudio, hideToast, showToast, i18n]); +} - useEffect(() => { - if (toast?.type === 'dismissable') { - clearTimeoutIfNecessary(timeoutRef.current); - timeoutRef.current = setTimeout(dismissToast, DEFAULT_LIFETIME); +function useOutgoingRingToast({ + outgoingRing, + i18n, +}: { + outgoingRing?: boolean; + i18n: LocalizerType; +}): void { + const { showToast, hideToast } = useCallingToasts(); + const previousOutgoingRing = usePrevious(outgoingRing, outgoingRing); + const RINGING_TOAST_KEY = 'ringing'; + + React.useEffect(() => { + if (outgoingRing === undefined) { + return; } - return () => { - clearTimeoutIfNecessary(timeoutRef.current); - }; - }, [dismissToast, setIsVisible, timeoutRef, toast]); + if ( + previousOutgoingRing !== undefined && + outgoingRing !== previousOutgoingRing + ) { + hideToast(RINGING_TOAST_KEY); + showToast({ + key: RINGING_TOAST_KEY, + content: outgoingRing + ? i18n('icu:CallControls__RingingToast--ringing-on') + : i18n('icu:CallControls__RingingToast--ringing-off'), + autoClose: true, + dismissable: true, + }); + } + }, [outgoingRing, previousOutgoingRing, hideToast, showToast, i18n]); +} +function useRaisedHandsToast({ + raisedHands, + renderRaisedHandsToast, +}: { + raisedHands?: Set; + renderRaisedHandsToast?: ( + hands: Array + ) => JSX.Element | string | undefined; +}): void { + const RAISED_HANDS_TOAST_KEY = 'raised-hands'; + const LOAD_DELAY = 2000; + const { showToast, hideToast } = useCallingToasts(); + + // Hand state is updated after a delay upon joining a call, so it can appear that + // hands were raised immediately when you join a call. To avoid spurious toasts, add + // an initial delay before showing toasts. + const [isLoaded, setIsLoaded] = React.useState(false); + React.useEffect(() => { + const timeout = setTimeout(() => { + setIsLoaded(true); + }, LOAD_DELAY); + return () => clearTimeout(timeout); + }, []); + + const previousRaisedHands = usePrevious(raisedHands, raisedHands); + const [newHands, loweredHands]: [Set, Set] = isLoaded + ? [ + setDifference( + raisedHands ?? new Set(), + previousRaisedHands ?? new Set() + ), + setDifference( + previousRaisedHands ?? new Set(), + raisedHands ?? new Set() + ), + ] + : [new Set(), new Set()]; + + const raisedHandsInLastShownToastRef = useRef>(new Set()); + const raisedHandsInLastShownToast = raisedHandsInLastShownToastRef.current; + + React.useEffect(() => { + // 1. If no hands are raised, then hide any raise hand toast. + // 2. Check if someone lowered their hand which they had recently raised. The + // previous toast saying they raised their hand would now be out of date, so we + // should hide it. + if ( + raisedHands?.size === 0 || + (raisedHandsInLastShownToast.size > 0 && + loweredHands.size > 0 && + setIsEqual(raisedHandsInLastShownToast, loweredHands)) + ) { + hideToast(RAISED_HANDS_TOAST_KEY); + } + + if (newHands.size === 0 || !renderRaisedHandsToast) { + return; + } + + const content = renderRaisedHandsToast([...newHands].reverse()); + if (!content) { + log.warn( + 'CallingToastManager useRaisedHandsToast: Failed to call renderRaisedHandsToast()' + ); + return; + } + + hideToast(RAISED_HANDS_TOAST_KEY); + // Note: Don't set { dismissable: true } or else the links (Lower or View Queue) + // will cause nested buttons (dismissable toasts are + + + + {hasEmptyResults && ( +

+ {currentQuery === '' ? ( + i18n('icu:CallsList__EmptyState--noQuery') + ) : ( + , + }} + /> + )} +

+ )} + + + {(ref, size) => { + return ( +
+ {size != null && ( + + {({ onRowsRendered, registerChild }) => { + return ( + + ); + }} + + )} +
+ ); + }} +
+ + ); +} diff --git a/ts/components/CallsNewCall.tsx b/ts/components/CallsNewCall.tsx new file mode 100644 index 0000000000..1c29aa9ea2 --- /dev/null +++ b/ts/components/CallsNewCall.tsx @@ -0,0 +1,284 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { ChangeEvent } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; +import { partition } from 'lodash'; +import type { ListRowProps } from 'react-virtualized'; +import { List } from 'react-virtualized'; +import type { ConversationType } from '../state/ducks/conversations'; +import type { LocalizerType } from '../types/I18N'; +import { SearchInput } from './SearchInput'; +import { filterAndSortConversationsByRecent } from '../util/filterAndSortConversations'; +import { NavSidebarSearchHeader } from './NavSidebar'; +import { ListTile } from './ListTile'; +import { strictAssert } from '../util/assert'; +import { UserText } from './UserText'; +import { Avatar, AvatarSize } from './Avatar'; +import { Intl } from './Intl'; +import { SizeObserver } from '../hooks/useSizeObserver'; +import { CallType } from '../types/CallDisposition'; + +type CallsNewCallProps = Readonly<{ + hasActiveCall: boolean; + allConversations: ReadonlyArray; + i18n: LocalizerType; + onSelectConversation: (conversationId: string) => void; + onOutgoingAudioCallInConversation: (conversationId: string) => void; + onOutgoingVideoCallInConversation: (conversationId: string) => void; + regionCode: string | undefined; +}>; + +type Row = + | { kind: 'header'; title: string } + | { kind: 'conversation'; conversation: ConversationType }; + +export function CallsNewCallButton({ + callType, + hasActiveCall, + onClick, +}: { + callType: CallType; + hasActiveCall: boolean; + onClick: () => void; +}): JSX.Element { + return ( + + ); +} + +export function CallsNewCall({ + hasActiveCall, + allConversations, + i18n, + onSelectConversation, + onOutgoingAudioCallInConversation, + onOutgoingVideoCallInConversation, + regionCode, +}: CallsNewCallProps): JSX.Element { + const [queryInput, setQueryInput] = useState(''); + + const query = useMemo(() => { + return queryInput.toLowerCase().normalize().trim(); + }, [queryInput]); + + const activeConversations = useMemo(() => { + return allConversations.filter(conversation => { + return conversation.activeAt != null && conversation.isArchived !== true; + }); + }, [allConversations]); + + const filteredConversations = useMemo(() => { + if (query === '') { + return activeConversations; + } + return filterAndSortConversationsByRecent( + activeConversations, + query, + regionCode + ); + }, [activeConversations, query, regionCode]); + + const [groupConversations, directConversations] = useMemo(() => { + return partition(filteredConversations, conversation => { + return conversation.type === 'group'; + }); + }, [filteredConversations]); + + const handleSearchInputChange = useCallback( + (event: ChangeEvent) => { + setQueryInput(event.currentTarget.value); + }, + [] + ); + + const handleSearchInputClear = useCallback(() => { + setQueryInput(''); + }, []); + + const rows = useMemo((): ReadonlyArray => { + let result: Array = []; + if (directConversations.length > 0) { + result.push({ + kind: 'header', + title: 'Contacts', + }); + result = result.concat( + directConversations.map(conversation => { + return { + kind: 'conversation', + conversation, + }; + }) + ); + } + if (groupConversations.length > 0) { + result.push({ + kind: 'header', + title: 'Groups', + }); + result = result.concat( + groupConversations.map((conversation): Row => { + return { + kind: 'conversation', + conversation, + }; + }) + ); + } + return result; + }, [directConversations, groupConversations]); + + const isRowLoaded = useCallback( + ({ index }) => { + return rows.at(index) != null; + }, + [rows] + ); + + const rowHeight = useCallback( + ({ index }) => { + if (rows.at(index)?.kind === 'conversation') { + return ListTile.heightCompact; + } + // Height of .CallsNewCall__ListHeaderItem + return 40; + }, + [rows] + ); + + const rowRenderer = useCallback( + ({ key, index, style }: ListRowProps) => { + const item = rows.at(index); + strictAssert(item != null, 'Rendered non-existent row'); + + if (item.kind === 'header') { + return ( +
+ {item.title} +
+ ); + } + + return ( +
+ + } + title={} + trailing={ +
+ {item.conversation.type === 'direct' && ( + { + onOutgoingAudioCallInConversation(item.conversation.id); + }} + /> + )} + { + onOutgoingVideoCallInConversation(item.conversation.id); + }} + /> +
+ } + onClick={() => { + onSelectConversation(item.conversation.id); + }} + /> +
+ ); + }, + [ + rows, + i18n, + hasActiveCall, + onSelectConversation, + onOutgoingAudioCallInConversation, + onOutgoingVideoCallInConversation, + ] + ); + + return ( + <> + + + + {rows.length === 0 && ( +
+ {query === '' ? ( + i18n('icu:CallsNewCall__EmptyState--noQuery') + ) : ( + , + }} + /> + )} +
+ )} + {rows.length > 0 && ( + + {(ref, size) => { + return ( +
+ {size != null && ( + + )} +
+ ); + }} +
+ )} + + ); +} diff --git a/ts/components/CallsTab.tsx b/ts/components/CallsTab.tsx new file mode 100644 index 0000000000..37bdadea78 --- /dev/null +++ b/ts/components/CallsTab.tsx @@ -0,0 +1,297 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import React, { useCallback, useEffect, useState } from 'react'; +import type { LocalizerType } from '../types/I18N'; +import { NavSidebar, NavSidebarActionButton } from './NavSidebar'; +import { CallsList } from './CallsList'; +import type { ConversationType } from '../state/ducks/conversations'; +import type { + CallHistoryFilterOptions, + CallHistoryGroup, + CallHistoryPagination, +} from '../types/CallDisposition'; +import { CallsNewCall } from './CallsNewCall'; +import { useEscapeHandling } from '../hooks/useEscapeHandling'; +import type { ActiveCallStateType } from '../state/ducks/calling'; +import { ContextMenu } from './ContextMenu'; +import { ConfirmationDialog } from './ConfirmationDialog'; +import type { UnreadStats } from '../util/countUnreadStats'; + +enum CallsTabSidebarView { + CallsListView, + NewCallView, +} + +type CallsTabProps = Readonly<{ + activeCall: ActiveCallStateType | undefined; + allConversations: ReadonlyArray; + otherTabsUnreadStats: UnreadStats; + getCallHistoryGroupsCount: ( + options: CallHistoryFilterOptions + ) => Promise; + getCallHistoryGroups: ( + options: CallHistoryFilterOptions, + pagination: CallHistoryPagination + ) => Promise>; + callHistoryEdition: number; + getConversation: (id: string) => ConversationType | void; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + i18n: LocalizerType; + navTabsCollapsed: boolean; + onClearCallHistory: () => void; + onMarkCallHistoryRead: (conversationId: string, callId: string) => void; + onToggleNavTabsCollapse: (navTabsCollapsed: boolean) => void; + onOutgoingAudioCallInConversation: (conversationId: string) => void; + onOutgoingVideoCallInConversation: (conversationId: string) => void; + preferredLeftPaneWidth: number; + renderConversationDetails: ( + conversationId: string, + callHistoryGroup: CallHistoryGroup | null + ) => JSX.Element; + regionCode: string | undefined; + savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void; +}>; + +export function CallsTab({ + activeCall, + allConversations, + otherTabsUnreadStats, + getCallHistoryGroupsCount, + getCallHistoryGroups, + callHistoryEdition, + getConversation, + hasFailedStorySends, + hasPendingUpdate, + i18n, + navTabsCollapsed, + onClearCallHistory, + onMarkCallHistoryRead, + onToggleNavTabsCollapse, + onOutgoingAudioCallInConversation, + onOutgoingVideoCallInConversation, + preferredLeftPaneWidth, + renderConversationDetails, + regionCode, + savePreferredLeftPaneWidth, +}: CallsTabProps): JSX.Element { + const [sidebarView, setSidebarView] = useState( + CallsTabSidebarView.CallsListView + ); + const [selected, setSelected] = useState<{ + conversationId: string; + callHistoryGroup: CallHistoryGroup | null; + } | null>(null); + const [ + confirmClearCallHistoryDialogOpen, + setConfirmClearCallHistoryDialogOpen, + ] = useState(false); + + const updateSidebarView = useCallback( + (newSidebarView: CallsTabSidebarView) => { + setSidebarView(newSidebarView); + setSelected(null); + }, + [] + ); + + const handleSelectCallHistoryGroup = useCallback( + (conversationId: string, callHistoryGroup: CallHistoryGroup) => { + setSelected({ + conversationId, + callHistoryGroup, + }); + }, + [] + ); + + const handleSelectConversation = useCallback((conversationId: string) => { + setSelected({ conversationId, callHistoryGroup: null }); + }, []); + + useEscapeHandling( + sidebarView === CallsTabSidebarView.NewCallView + ? () => { + updateSidebarView(CallsTabSidebarView.CallsListView); + } + : undefined + ); + + const handleOpenClearCallHistoryDialog = useCallback(() => { + setConfirmClearCallHistoryDialogOpen(true); + }, []); + + const handleCloseClearCallHistoryDialog = useCallback(() => { + setConfirmClearCallHistoryDialogOpen(false); + }, []); + + const handleOutgoingAudioCallInConversation = useCallback( + (conversationId: string) => { + onOutgoingAudioCallInConversation(conversationId); + updateSidebarView(CallsTabSidebarView.CallsListView); + }, + [updateSidebarView, onOutgoingAudioCallInConversation] + ); + + const handleOutgoingVideoCallInConversation = useCallback( + (conversationId: string) => { + onOutgoingVideoCallInConversation(conversationId); + updateSidebarView(CallsTabSidebarView.CallsListView); + }, + [updateSidebarView, onOutgoingVideoCallInConversation] + ); + + useEffect(() => { + if (selected?.callHistoryGroup != null) { + selected.callHistoryGroup.children.forEach(child => { + onMarkCallHistoryRead(selected.conversationId, child.callId); + }); + } + }, [selected, onMarkCallHistoryRead]); + + return ( + <> +
+ { + updateSidebarView(CallsTabSidebarView.CallsListView); + } + : null + } + onToggleNavTabsCollapse={onToggleNavTabsCollapse} + requiresFullWidth + preferredLeftPaneWidth={preferredLeftPaneWidth} + savePreferredLeftPaneWidth={savePreferredLeftPaneWidth} + actions={ + <> + {sidebarView === CallsTabSidebarView.CallsListView && ( + <> + } + label={i18n('icu:CallsTab__NewCallActionLabel')} + onClick={() => { + updateSidebarView(CallsTabSidebarView.NewCallView); + }} + /> + + {({ openMenu, onKeyDown }) => { + return ( + } + label={i18n('icu:CallsTab__MoreActionsLabel')} + /> + ); + }} + + + )} + + } + > + {sidebarView === CallsTabSidebarView.CallsListView && ( + + )} + {sidebarView === CallsTabSidebarView.NewCallView && ( + + )} + + {selected == null ? ( +
+
+

+ {i18n('icu:CallsTab__EmptyStateText')} +

+
+ ) : ( +
+ {renderConversationDetails( + selected.conversationId, + selected.callHistoryGroup + )} +
+ )} +
+ {confirmClearCallHistoryDialogOpen && ( + + {i18n('icu:CallsTab__ConfirmClearCallHistory__Body')} + + )} + + ); +} diff --git a/ts/components/CaptchaDialog.stories.tsx b/ts/components/CaptchaDialog.stories.tsx index b52aefd6be..d9071414db 100644 --- a/ts/components/CaptchaDialog.stories.tsx +++ b/ts/components/CaptchaDialog.stories.tsx @@ -3,36 +3,33 @@ import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; -import { boolean } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './CaptchaDialog'; import { CaptchaDialog } from './CaptchaDialog'; import { Button } from './Button'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; -export default { - title: 'Components/CaptchaDialog', -}; - const i18n = setupI18n('en', enMessages); -export const _CaptchaDialog = (): JSX.Element => { +export default { + title: 'Components/CaptchaDialog', + argTypes: { + isPending: { control: { type: 'boolean' } }, + }, + args: { + i18n, + isPending: false, + onContinue: action('onContinue'), + }, +} satisfies Meta; + +export function Basic(args: PropsType): JSX.Element { const [isSkipped, setIsSkipped] = useState(false); if (isSkipped) { return ; } - return ( - setIsSkipped(true)} - /> - ); -}; - -_CaptchaDialog.story = { - name: 'CaptchaDialog', -}; + return setIsSkipped(true)} />; +} diff --git a/ts/components/CaptchaDialog.tsx b/ts/components/CaptchaDialog.tsx index 8f864f0a0d..0b9091960d 100644 --- a/ts/components/CaptchaDialog.tsx +++ b/ts/components/CaptchaDialog.tsx @@ -8,7 +8,7 @@ import { Button, ButtonVariant } from './Button'; import { Modal } from './Modal'; import { Spinner } from './Spinner'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; isPending: boolean; diff --git a/ts/components/ChatColorPicker.stories.tsx b/ts/components/ChatColorPicker.stories.tsx index 597caa4e74..c8b534115b 100644 --- a/ts/components/ChatColorPicker.stories.tsx +++ b/ts/components/ChatColorPicker.stories.tsx @@ -2,21 +2,45 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; - import { action } from '@storybook/addon-actions'; -import { select } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import type { PropsType } from './ChatColorPicker'; import { ChatColorPicker } from './ChatColorPicker'; import { ConversationColors } from '../types/Colors'; import { setupI18n } from '../util/setupI18n'; +const i18n = setupI18n('en', enMessages); + export default { title: 'Components/ChatColorPicker', -}; - -const i18n = setupI18n('en', enMessages); + argTypes: { + selectedColor: { + control: { + type: 'select', + options: ConversationColors, + }, + }, + }, + args: { + addCustomColor: action('addCustomColor'), + colorSelected: action('colorSelected'), + editCustomColor: action('editCustomColor'), + getConversationsWithCustomColor: (_: string) => Promise.resolve([]), + i18n, + removeCustomColor: action('removeCustomColor'), + removeCustomColorOnConversations: action( + 'removeCustomColorOnConversations' + ), + resetAllChatColors: action('resetAllChatColors'), + resetDefaultChatColor: action('resetDefaultChatColor'), + selectedColor: 'basil', + selectedCustomColor: {}, + setGlobalDefaultConversationColor: action( + 'setGlobalDefaultConversationColor' + ), + }, +} satisfies Meta; const SAMPLE_CUSTOM_COLOR = { deg: 90, @@ -24,25 +48,8 @@ const SAMPLE_CUSTOM_COLOR = { start: { hue: 315, saturation: 78 }, }; -const createProps = (): PropsType => ({ - addCustomColor: action('addCustomColor'), - colorSelected: action('colorSelected'), - editCustomColor: action('editCustomColor'), - getConversationsWithCustomColor: (_: string) => Promise.resolve([]), - i18n, - removeCustomColor: action('removeCustomColor'), - removeCustomColorOnConversations: action('removeCustomColorOnConversations'), - resetAllChatColors: action('resetAllChatColors'), - resetDefaultChatColor: action('resetDefaultChatColor'), - selectedColor: select('selectedColor', ConversationColors, 'basil' as const), - selectedCustomColor: {}, - setGlobalDefaultConversationColor: action( - 'setGlobalDefaultConversationColor' - ), -}); - -export function Default(): JSX.Element { - return ; +export function Default(args: PropsType): JSX.Element { + return ; } const CUSTOM_COLORS = { @@ -62,10 +69,10 @@ const CUSTOM_COLORS = { }, }; -export function CustomColors(): JSX.Element { +export function CustomColors(args: PropsType): JSX.Element { return ( void; + prevConversationId: string | undefined; + renderConversationView: () => JSX.Element; + renderLeftPane: (props: NavTabPanelProps) => JSX.Element; + renderMiniPlayer: (options: { shouldFlow: boolean }) => JSX.Element; + selectedConversationId: string | undefined; + showWhatsNewModal: () => unknown; +}>; + +export function ChatsTab({ + otherTabsUnreadStats, + i18n, + hasPendingUpdate, + hasFailedStorySends, + navTabsCollapsed, + onToggleNavTabsCollapse, + prevConversationId, + renderConversationView, + renderLeftPane, + renderMiniPlayer, + selectedConversationId, + showWhatsNewModal, +}: ChatsTabProps): JSX.Element { + return ( + <> +
+ {renderLeftPane({ + otherTabsUnreadStats, + collapsed: navTabsCollapsed, + hasPendingUpdate, + hasFailedStorySends, + onToggleCollapse: onToggleNavTabsCollapse, + })} +
+
+
+ {selectedConversationId && ( +
+ {renderConversationView()} +
+ )} + {!prevConversationId && ( +
+ {renderMiniPlayer({ shouldFlow: false })} +
+

+ {getEnvironment() !== Environment.Staging + ? i18n('icu:welcomeToSignal') + : 'THIS IS A STAGING DESKTOP'} +

+

+ +

+
+ )} +
+ + ); +} diff --git a/ts/components/Checkbox.stories.tsx b/ts/components/Checkbox.stories.tsx index 4f0034efec..03a62196aa 100644 --- a/ts/components/Checkbox.stories.tsx +++ b/ts/components/Checkbox.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './Checkbox'; import { Checkbox } from './Checkbox'; @@ -16,7 +17,7 @@ const createProps = (): PropsType => ({ export default { title: 'Components/Checkbox', -}; +} satisfies Meta; export function Normal(): JSX.Element { return ; diff --git a/ts/components/CircleCheckbox.stories.tsx b/ts/components/CircleCheckbox.stories.tsx index 0a7260251e..1e8b033b3f 100644 --- a/ts/components/CircleCheckbox.stories.tsx +++ b/ts/components/CircleCheckbox.stories.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import type { Props } from './CircleCheckbox'; import { CircleCheckbox, Variant } from './CircleCheckbox'; @@ -15,7 +15,7 @@ const createProps = (): Props => ({ export default { title: 'Components/CircleCheckbox', -}; +} satisfies Meta; export function Normal(): JSX.Element { return ; diff --git a/ts/components/ClearingData.stories.tsx b/ts/components/ClearingData.stories.tsx index 3dacf136b6..e6e183f841 100644 --- a/ts/components/ClearingData.stories.tsx +++ b/ts/components/ClearingData.stories.tsx @@ -2,23 +2,19 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; - import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; - +import type { PropsType } from './ClearingData'; import { ClearingData } from './ClearingData'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/ClearingData', -}; +} satisfies Meta; -export const _ClearingData = (): JSX.Element => ( - -); - -_ClearingData.story = { - name: 'Clearing data', -}; +export function Basic(): JSX.Element { + return ; +} diff --git a/ts/components/CompositionArea.stories.tsx b/ts/components/CompositionArea.stories.tsx index 97d6893451..3dde92c340 100644 --- a/ts/components/CompositionArea.stories.tsx +++ b/ts/components/CompositionArea.stories.tsx @@ -1,12 +1,9 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { DecoratorFunction } from '@storybook/addons'; -import * as React from 'react'; - +import React, { useContext } from 'react'; import { action } from '@storybook/addon-actions'; -import { boolean, select } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import { IMAGE_JPEG } from '../types/MIME'; import type { Props } from './CompositionArea'; import { CompositionArea } from './CompositionArea'; @@ -28,286 +25,256 @@ export default { decorators: [ // necessary for the add attachment button to render properly storyFn =>
{storyFn()}
, - ] as Array>, -}; + ], + argTypes: { + recordingState: { + control: { type: 'select' }, + options: Object.keys(RecordingState), + mappings: RecordingState, + }, + messageRequestsEnabled: { control: { type: 'boolean' } }, + announcementsOnly: { control: { type: 'boolean' } }, + areWePendingApproval: { control: { type: 'boolean' } }, + }, + args: { + addAttachment: action('addAttachment'), + conversationId: '123', + convertDraftBodyRangesIntoHydrated: () => undefined, + discardEditMessage: action('discardEditMessage'), + focusCounter: 0, + sendCounter: 0, + i18n, + isDisabled: false, + isFormattingFlagEnabled: true, + isFormattingSpoilersFlagEnabled: true, + isFormattingEnabled: true, + messageCompositionId: '456', + sendEditedMessage: action('sendEditedMessage'), + sendMultiMediaMessage: action('sendMultiMediaMessage'), + platform: 'darwin', + processAttachments: action('processAttachments'), + removeAttachment: action('removeAttachment'), + setComposerFocus: action('setComposerFocus'), + setMessageToEdit: action('setMessageToEdit'), + setQuoteByMessageId: action('setQuoteByMessageId'), + showToast: action('showToast'), -const useProps = (overrideProps: Partial = {}): Props => ({ - addAttachment: action('addAttachment'), - conversationId: '123', - discardEditMessage: action('discardEditMessage'), - focusCounter: 0, - sendCounter: 0, - i18n, - isDisabled: false, - isFormattingFlagEnabled: - overrideProps.isFormattingFlagEnabled === false - ? overrideProps.isFormattingFlagEnabled - : true, - isFormattingSpoilersFlagEnabled: - overrideProps.isFormattingSpoilersFlagEnabled === false - ? overrideProps.isFormattingSpoilersFlagEnabled - : true, - isFormattingEnabled: - overrideProps.isFormattingEnabled === false - ? overrideProps.isFormattingEnabled - : true, - messageCompositionId: '456', - sendEditedMessage: action('sendEditedMessage'), - sendMultiMediaMessage: action('sendMultiMediaMessage'), - platform: 'darwin', - processAttachments: action('processAttachments'), - removeAttachment: action('removeAttachment'), - theme: React.useContext(StorybookThemeContext), - setComposerFocus: action('setComposerFocus'), - setMessageToEdit: action('setMessageToEdit'), - setQuoteByMessageId: action('setQuoteByMessageId'), - showToast: action('showToast'), + // AttachmentList + draftAttachments: [], + onClearAttachments: action('onClearAttachments'), + // AudioCapture + cancelRecording: action('cancelRecording'), + completeRecording: action('completeRecording'), + errorRecording: action('errorRecording'), + recordingState: RecordingState.Idle, + startRecording: action('startRecording'), + // StagedLinkPreview + linkPreviewLoading: false, + linkPreviewResult: undefined, + onCloseLinkPreview: action('onCloseLinkPreview'), + // Quote + quotedMessageProps: undefined, + scrollToMessage: action('scrollToMessage'), + // MediaEditor + imageToBlurHash: async () => 'LDA,FDBnm+I=p{tkIUI;~UkpELV]', + // MediaQualitySelector + setMediaQualitySetting: action('setMediaQualitySetting'), + shouldSendHighQualityAttachments: false, + // CompositionInput + onEditorStateChange: action('onEditorStateChange'), + onTextTooLong: action('onTextTooLong'), + draftText: undefined, + clearQuotedMessage: action('clearQuotedMessage'), + getPreferredBadge: () => undefined, + getQuotedMessage: action('getQuotedMessage'), + sortedGroupMembers: [], + // EmojiButton + onPickEmoji: action('onPickEmoji'), + onSetSkinTone: action('onSetSkinTone'), + recentEmojis: [], + skinTone: 1, + // StickerButton + knownPacks: [], + receivedPacks: [], + installedPacks: [], + blessedPacks: [], + recentStickers: [], + clearInstalledStickerPack: action('clearInstalledStickerPack'), + pushPanelForConversation: action('pushPanelForConversation'), + sendStickerMessage: action('sendStickerMessage'), + clearShowIntroduction: action('clearShowIntroduction'), + showPickerHint: false, + clearShowPickerHint: action('clearShowPickerHint'), + // Message Requests + conversationType: 'direct', + acceptConversation: action('acceptConversation'), + blockConversation: action('blockConversation'), + blockAndReportSpam: action('blockAndReportSpam'), + deleteConversation: action('deleteConversation'), + messageRequestsEnabled: false, + title: '', + // GroupV1 Disabled Actions + showGV2MigrationDialog: action('showGV2MigrationDialog'), + // GroupV2 + announcementsOnly: false, + areWeAdmin: false, + areWePendingApproval: false, + groupAdmins: [], + cancelJoinRequest: action('cancelJoinRequest'), + showConversation: action('showConversation'), + // SMS-only + isSMSOnly: false, + isFetchingUUID: false, + renderSmartCompositionRecording: _ =>
RECORDING
, + renderSmartCompositionRecordingDraft: _ =>
RECORDING DRAFT
, + // Select mode + selectedMessageIds: undefined, + toggleSelectMode: action('toggleSelectMode'), + toggleForwardMessagesModal: action('toggleForwardMessagesModal'), + }, +} satisfies Meta; - // AttachmentList - draftAttachments: overrideProps.draftAttachments || [], - onClearAttachments: action('onClearAttachments'), - // AudioCapture - cancelRecording: action('cancelRecording'), - completeRecording: action('completeRecording'), - errorRecording: action('errorRecording'), - recordingState: select( - 'recordingState', - RecordingState, - overrideProps.recordingState || RecordingState.Idle - ), - startRecording: action('startRecording'), - // StagedLinkPreview - linkPreviewLoading: Boolean(overrideProps.linkPreviewLoading), - linkPreviewResult: overrideProps.linkPreviewResult, - onCloseLinkPreview: action('onCloseLinkPreview'), - // Quote - quotedMessageProps: overrideProps.quotedMessageProps, - scrollToMessage: action('scrollToMessage'), - // MediaEditor - imageToBlurHash: async () => 'LDA,FDBnm+I=p{tkIUI;~UkpELV]', - // MediaQualitySelector - setMediaQualitySetting: action('setMediaQualitySetting'), - shouldSendHighQualityAttachments: Boolean( - overrideProps.shouldSendHighQualityAttachments - ), - // CompositionInput - onEditorStateChange: action('onEditorStateChange'), - onTextTooLong: action('onTextTooLong'), - draftText: overrideProps.draftText || undefined, - clearQuotedMessage: action('clearQuotedMessage'), - getPreferredBadge: () => undefined, - getQuotedMessage: action('getQuotedMessage'), - sortedGroupMembers: [], - // EmojiButton - onPickEmoji: action('onPickEmoji'), - onSetSkinTone: action('onSetSkinTone'), - recentEmojis: [], - skinTone: 1, - // StickerButton - knownPacks: overrideProps.knownPacks || [], - receivedPacks: [], - installedPacks: [], - blessedPacks: [], - recentStickers: [], - clearInstalledStickerPack: action('clearInstalledStickerPack'), - pushPanelForConversation: action('pushPanelForConversation'), - sendStickerMessage: action('sendStickerMessage'), - clearShowIntroduction: action('clearShowIntroduction'), - showPickerHint: false, - clearShowPickerHint: action('clearShowPickerHint'), - // Message Requests - conversationType: 'direct', - acceptConversation: action('acceptConversation'), - blockConversation: action('blockConversation'), - blockAndReportSpam: action('blockAndReportSpam'), - deleteConversation: action('deleteConversation'), - messageRequestsEnabled: boolean( - 'messageRequestsEnabled', - overrideProps.messageRequestsEnabled || false - ), - title: '', - // GroupV1 Disabled Actions - showGV2MigrationDialog: action('showGV2MigrationDialog'), - // GroupV2 - announcementsOnly: boolean( - 'announcementsOnly', - Boolean(overrideProps.announcementsOnly) - ), - areWeAdmin: boolean('areWeAdmin', Boolean(overrideProps.areWeAdmin)), - areWePendingApproval: boolean( - 'areWePendingApproval', - Boolean(overrideProps.areWePendingApproval) - ), - groupAdmins: [], - cancelJoinRequest: action('cancelJoinRequest'), - showConversation: action('showConversation'), - // SMS-only - isSMSOnly: overrideProps.isSMSOnly || false, - isFetchingUUID: overrideProps.isFetchingUUID || false, - renderSmartCompositionRecording: _ =>
RECORDING
, - renderSmartCompositionRecordingDraft: _ =>
RECORDING DRAFT
, - // Select mode - selectedMessageIds: undefined, - toggleSelectMode: action('toggleSelectMode'), - toggleForwardMessagesModal: action('toggleForwardMessagesModal'), -}); - -export function Default(): JSX.Element { - const props = useProps(); - - return ; +export function Default(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ; } -export function StartingText(): JSX.Element { - const props = useProps({ - draftText: "here's some starting text", - }); - - return ; -} - -export function StickerButton(): JSX.Element { - const props = useProps({ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - knownPacks: [{} as any], - }); - - return ; -} - -export function MessageRequest(): JSX.Element { - const props = useProps({ - messageRequestsEnabled: true, - }); - - return ; -} - -export function SmsOnlyFetchingUuid(): JSX.Element { - const props = useProps({ - isSMSOnly: true, - isFetchingUUID: true, - }); - - return ; -} - -SmsOnlyFetchingUuid.story = { - name: 'SMS-only fetching UUID', -}; - -export function SmsOnly(): JSX.Element { - const props = useProps({ - isSMSOnly: true, - }); - - return ; -} - -SmsOnly.story = { - name: 'SMS-only', -}; - -export function Attachments(): JSX.Element { - const props = useProps({ - draftAttachments: [ - fakeDraftAttachment({ - contentType: IMAGE_JPEG, - url: landscapeGreenUrl, - }), - ], - }); - - return ; -} - -export function PendingApproval(): JSX.Element { +export function StartingText(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); return ( ); } -AnnouncementsOnlyGroup.story = { - name: 'Announcements Only group', -}; - -export function AnnouncementsOnlyGroup(): JSX.Element { +export function StickerButton(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); return ( ); } -AnnouncementsOnlyGroup.story = { - name: 'Announcements Only group', -}; +export function MessageRequest(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ; +} -export function Quote(): JSX.Element { +export function SmsOnlyFetchingUuid(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ; +} + +export function SmsOnly(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ; +} + +export function Attachments(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); return ( + ); +} + +export function PendingApproval(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ; +} + +export function AnnouncementsOnlyGroup(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ( + + ); +} + +export function Quote(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ( + + ); +} + +export function QuoteWithPayment(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ( + ); } -export function QuoteWithPayment(): JSX.Element { +export function NoFormattingMenu(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ( + + ); +} + +export function NoFormattingFlag(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); + return ( + + ); +} + +export function NoSpoilerFormattingFlag(args: Props): JSX.Element { + const theme = useContext(StorybookThemeContext); return ( - ); -} - -QuoteWithPayment.story = { - name: 'Quote with payment', -}; - -export function NoFormattingMenu(): JSX.Element { - return ; -} - -export function NoFormattingFlag(): JSX.Element { - return ; -} - -export function NoSpoilerFormattingFlag(): JSX.Element { - return ( - ); } diff --git a/ts/components/CompositionArea.tsx b/ts/components/CompositionArea.tsx index 1c505fc6d7..71f128cd99 100644 --- a/ts/components/CompositionArea.tsx +++ b/ts/components/CompositionArea.tsx @@ -5,7 +5,10 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import classNames from 'classnames'; import type { ReadonlyDeep } from 'type-fest'; -import type { DraftBodyRanges } from '../types/BodyRange'; +import type { + DraftBodyRanges, + HydratedBodyRangesType, +} from '../types/BodyRange'; import type { LocalizerType, ThemeType } from '../types/Util'; import type { ErrorDialogAudioRecorderType } from '../types/AudioRecorder'; import { RecordingState } from '../types/AudioRecorder'; @@ -36,6 +39,7 @@ import type { InMemoryAttachmentDraftType, } from '../types/Attachment'; import { isImageAttachment, isVoiceMessage } from '../types/Attachment'; +import type { AciString } from '../types/ServiceId'; import { AudioCapture } from './conversation/AudioCapture'; import { CompositionUpload } from './CompositionUpload'; import type { @@ -84,10 +88,12 @@ export type OwnProps = Readonly<{ conversationId: string, onRecordingComplete: (rec: InMemoryAttachmentDraftType) => unknown ) => unknown; + convertDraftBodyRangesIntoHydrated: ( + bodyRanges: DraftBodyRanges | undefined + ) => HydratedBodyRangesType | undefined; conversationId: string; discardEditMessage: (id: string) => unknown; draftEditMessage?: DraftEditMessageType; - uuid?: string; draftAttachments: ReadonlyArray; errorDialogAudioRecorderType?: ErrorDialogAudioRecorderType; errorRecording: (e: ErrorDialogAudioRecorderType) => unknown; @@ -131,7 +137,7 @@ export type OwnProps = Readonly<{ options: { bodyRanges?: DraftBodyRanges; message?: string; - quoteAuthorUuid?: string; + quoteAuthorAci?: AciString; quoteSentAt?: number; targetMessageId: string; } @@ -153,7 +159,7 @@ export type OwnProps = Readonly<{ 'i18n' | 'onClick' | 'onClose' | 'withContentAbove' | 'isCompose' > >; - quotedMessageAuthorUuid?: string; + quotedMessageAuthorAci?: AciString; quotedMessageSentAt?: number; removeAttachment: (conversationId: string, filePath: string) => unknown; @@ -221,6 +227,7 @@ export function CompositionArea({ // Base props addAttachment, conversationId, + convertDraftBodyRangesIntoHydrated, discardEditMessage, draftEditMessage, focusCounter, @@ -256,7 +263,7 @@ export function CompositionArea({ // Quote quotedMessageId, quotedMessageProps, - quotedMessageAuthorUuid, + quotedMessageAuthorAci, quotedMessageSentAt, scrollToMessage, // MediaQualitySelector @@ -356,7 +363,7 @@ export function CompositionArea({ message, // sent timestamp for the quote quoteSentAt: quotedMessageSentAt, - quoteAuthorUuid: quotedMessageAuthorUuid, + quoteAuthorAci: quotedMessageAuthorAci, targetMessageId: editedMessageId, }); } else { @@ -374,7 +381,7 @@ export function CompositionArea({ draftAttachments, editedMessageId, quotedMessageSentAt, - quotedMessageAuthorUuid, + quotedMessageAuthorAci, sendEditedMessage, sendMultiMediaMessage, setLarge, @@ -434,12 +441,14 @@ export function CompositionArea({ useEffect(() => { if (inputApiRef.current) { inputApiRef.current.focus(); + setHasFocus(true); } }, []); // Focus input whenever explicitly requested useEffect(() => { if (focusCounter !== previousFocusCounter && inputApiRef.current) { inputApiRef.current.focus(); + setHasFocus(true); } }, [inputApiRef, focusCounter, previousFocusCounter]); @@ -534,7 +543,6 @@ export function CompositionArea({ setComposerFocus(conversationId)} recentEmojis={recentEmojis} @@ -851,12 +859,25 @@ export function CompositionArea({ 'url' in attachmentToEdit && attachmentToEdit.url && ( setAttachmentToEdit(undefined)} - onDone={({ data, contentType, blurHash }) => { + onDone={({ + caption, + captionBodyRanges, + data, + contentType, + blurHash, + }) => { const newAttachment = { ...attachmentToEdit, contentType, @@ -867,9 +888,25 @@ export function CompositionArea({ addAttachment(conversationId, newAttachment); setAttachmentToEdit(undefined); + onEditorStateChange?.({ + bodyRanges: captionBodyRanges ?? [], + conversationId, + messageText: caption ?? '', + sendCounter, + }); + + inputApiRef.current?.setContents( + caption ?? '', + convertDraftBodyRangesIntoHydrated(captionBodyRanges), + true + ); }} - installedPacks={installedPacks} + onPickEmoji={onPickEmoji} + onTextTooLong={onTextTooLong} + platform={platform} recentStickers={recentStickers} + skinTone={skinTone} + sortedGroupMembers={sortedGroupMembers} /> )}
diff --git a/ts/components/CompositionInput.stories.tsx b/ts/components/CompositionInput.stories.tsx index 48834ff2a6..86371085bd 100644 --- a/ts/components/CompositionInput.stories.tsx +++ b/ts/components/CompositionInput.stories.tsx @@ -2,15 +2,14 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import 'react-quill/dist/quill.core.css'; -import { boolean, select } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import type { Props } from './CompositionInput'; import { CompositionInput } from './CompositionInput'; import { setupI18n } from '../util/setupI18n'; +import { generateAci } from '../types/ServiceId'; import enMessages from '../../_locales/en/messages.json'; import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext'; @@ -18,11 +17,13 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/CompositionInput', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const useProps = (overrideProps: Partial = {}): Props => ({ i18n, - disabled: boolean('disabled', overrideProps.disabled || false), + disabled: overrideProps.disabled ?? false, draftText: overrideProps.draftText || undefined, draftBodyRanges: overrideProps.draftBodyRanges || [], clearQuotedMessage: action('clearQuotedMessage'), @@ -40,7 +41,7 @@ const useProps = (overrideProps: Partial = {}): Props => ({ overrideProps.isFormattingEnabled === false ? overrideProps.isFormattingEnabled : true, - large: boolean('large', overrideProps.large || false), + large: overrideProps.large ?? false, onCloseLinkPreview: action('onCloseLinkPreview'), onEditorStateChange: action('onEditorStateChange'), onPickEmoji: action('onPickEmoji'), @@ -48,19 +49,8 @@ const useProps = (overrideProps: Partial = {}): Props => ({ onTextTooLong: action('onTextTooLong'), platform: 'darwin', sendCounter: 0, - sortedGroupMembers: overrideProps.sortedGroupMembers || [], - skinTone: select( - 'skinTone', - { - skinTone0: 0, - skinTone1: 1, - skinTone2: 2, - skinTone3: 3, - skinTone4: 4, - skinTone5: 5, - }, - overrideProps.skinTone || undefined - ), + sortedGroupMembers: overrideProps.sortedGroupMembers ?? [], + skinTone: overrideProps.skinTone ?? undefined, theme: React.useContext(StorybookThemeContext), }); @@ -137,7 +127,7 @@ export function Mentions(): JSX.Element { { start: 5, length: 1, - mentionUuid: '0', + mentionAci: generateAci(), conversationID: 'k', replacementText: 'Kate Beaton', }, diff --git a/ts/components/CompositionInput.tsx b/ts/components/CompositionInput.tsx index 40caed6614..181661df7d 100644 --- a/ts/components/CompositionInput.tsx +++ b/ts/components/CompositionInput.tsx @@ -26,7 +26,7 @@ import { BodyRange, collapseRangeTree, insertRange } from '../types/BodyRange'; import type { LocalizerType, ThemeType } from '../types/Util'; import type { ConversationType } from '../state/ducks/conversations'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; -import { isValidUuid } from '../types/UUID'; +import { isAciString } from '../util/isAciString'; import { MentionBlot } from '../quill/mentions/blot'; import { matchEmojiImage, @@ -46,6 +46,7 @@ import { import { SignalClipboard } from '../quill/signal-clipboard'; import { DirectionalBlot } from '../quill/block/blot'; import { getClassNamesFor } from '../util/getClassNamesFor'; +import { isNotNil } from '../util/isNotNil'; import * as log from '../logging/log'; import * as Errors from '../types/errors'; import { useRefMerger } from '../hooks/useRefMerger'; @@ -677,11 +678,12 @@ export function CompositionInput(props: Props): React.ReactElement { return; } - const currentMemberUuids = currentMembers - .map(m => m.uuid) - .filter(isValidUuid); + const currentMemberAcis = currentMembers + .map(m => m.serviceId) + .filter(isNotNil) + .filter(isAciString); - const newDelta = getDeltaToRemoveStaleMentions(ops, currentMemberUuids); + const newDelta = getDeltaToRemoveStaleMentions(ops, currentMemberAcis); // eslint-disable-next-line @typescript-eslint/no-explicit-any quill.updateContents(newDelta as any); diff --git a/ts/components/CompositionRecording.stories.tsx b/ts/components/CompositionRecording.stories.tsx index d537c39447..7619ccb937 100644 --- a/ts/components/CompositionRecording.stories.tsx +++ b/ts/components/CompositionRecording.stories.tsx @@ -3,8 +3,9 @@ import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { Props } from './CompositionRecording'; import { CompositionRecording } from './CompositionRecording'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -13,7 +14,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'components/CompositionRecording', component: CompositionRecording, -}; +} satisfies Meta; export function Default(): JSX.Element { const [active, setActive] = useState(false); diff --git a/ts/components/CompositionRecordingDraft.stories.tsx b/ts/components/CompositionRecordingDraft.stories.tsx index 10d966b5a6..ac59696708 100644 --- a/ts/components/CompositionRecordingDraft.stories.tsx +++ b/ts/components/CompositionRecordingDraft.stories.tsx @@ -3,8 +3,9 @@ import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { Props } from './CompositionRecordingDraft'; import { CompositionRecordingDraft } from './CompositionRecordingDraft'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -13,7 +14,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'components/CompositionRecordingDraft', component: CompositionRecordingDraft, -}; +} satisfies Meta; export function Default(): JSX.Element { const [isPlaying, setIsPlaying] = useState(false); diff --git a/ts/components/CompositionRecordingDraft.tsx b/ts/components/CompositionRecordingDraft.tsx index ae26b10502..de09f672ec 100644 --- a/ts/components/CompositionRecordingDraft.tsx +++ b/ts/components/CompositionRecordingDraft.tsx @@ -11,7 +11,7 @@ import * as log from '../logging/log'; import type { Size } from '../hooks/useSizeObserver'; import { SizeObserver } from '../hooks/useSizeObserver'; -type Props = { +export type Props = { i18n: LocalizerType; audioUrl: string | undefined; active: diff --git a/ts/components/ConfirmDiscardDialog.stories.tsx b/ts/components/ConfirmDiscardDialog.stories.tsx index 9f3bb14976..04ef5da275 100644 --- a/ts/components/ConfirmDiscardDialog.stories.tsx +++ b/ts/components/ConfirmDiscardDialog.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -20,7 +21,7 @@ const createProps = (): PropsType => ({ export default { title: 'Components/ConfirmDiscardDialog', -}; +} satisfies Meta; export function Default(): JSX.Element { return ; diff --git a/ts/components/ConfirmationDialog.stories.tsx b/ts/components/ConfirmationDialog.stories.tsx index 7a3aec6b5a..629e19e1f4 100644 --- a/ts/components/ConfirmationDialog.stories.tsx +++ b/ts/components/ConfirmationDialog.stories.tsx @@ -4,6 +4,8 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { Props } from './ConfirmationDialog'; import { ConfirmationDialog } from './ConfirmationDialog'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -12,9 +14,9 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/ConfirmationDialog', -}; +} satisfies Meta; -export const _ConfirmationDialog = (): JSX.Element => { +export function Basic(): JSX.Element { return ( { asdf blip ); -}; - -_ConfirmationDialog.story = { - name: 'ConfirmationDialog', -}; +} export function CustomCancelText(): JSX.Element { return ( @@ -64,10 +62,6 @@ export function CustomCancelText(): JSX.Element { ); } -CustomCancelText.story = { - name: 'Custom cancel text', -}; - export function NoDefaultCancel(): JSX.Element { return ( ; type ContactType = Omit; @@ -54,10 +55,6 @@ export function EmptyList(): JSX.Element { return ; } -EmptyList.story = { - name: 'Empty list', -}; - export function OneContact(): JSX.Element { return ( @@ -66,10 +63,6 @@ export function OneContact(): JSX.Element { ); } -OneContact.story = { - name: 'One contact', -}; - export function ThreeContacts(): JSX.Element { return ( @@ -80,10 +73,6 @@ export function ThreeContacts(): JSX.Element { ); } -ThreeContacts.story = { - name: 'Three contacts', -}; - export function FourContactsOneWithALongName(): JSX.Element { return ( @@ -101,10 +90,6 @@ export function FourContactsOneWithALongName(): JSX.Element { ); } -FourContactsOneWithALongName.story = { - name: 'Four contacts, one with a long name', -}; - export function FiftyContacts(): JSX.Element { return ( @@ -114,7 +99,3 @@ export function FiftyContacts(): JSX.Element { ); } - -FiftyContacts.story = { - name: 'Fifty contacts', -}; diff --git a/ts/components/ContextMenu.stories.tsx b/ts/components/ContextMenu.stories.tsx index 5dc2b03831..cdb4e70f33 100644 --- a/ts/components/ContextMenu.stories.tsx +++ b/ts/components/ContextMenu.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './ContextMenu'; import { ContextMenu } from './ContextMenu'; import enMessages from '../../_locales/en/messages.json'; @@ -13,7 +14,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/ContextMenu', -}; +} satisfies Meta>; const getDefaultProps = (): PropsType => ({ i18n, diff --git a/ts/components/ContextMenu.tsx b/ts/components/ContextMenu.tsx index b9af3906a8..2f072f496a 100644 --- a/ts/components/ContextMenu.tsx +++ b/ts/components/ContextMenu.tsx @@ -97,6 +97,21 @@ export function ContextMenu({ } ); + // In Electron v23+, new elements added to the DOM may not trigger a recalculation of + // draggable regions, so if a ContextMenu is shown on top of a draggable region, its + // buttons may be unclickable. We add a class so that we can disable those draggable + // regions while the context menu is shown. It has the added benefit of ensuring that + // click events outside of the context menu onto an otherwise draggable region are + // propagated and trigger the menu to close. + useEffect(() => { + document.body.classList.toggle('context-menu-open', isMenuShowing); + }, [isMenuShowing]); + + useEffect(() => { + // Remove it on unmount in case the component is unmounted when the menu is open + return () => document.body.classList.remove('context-menu-open'); + }, []); + useEffect(() => { if (onMenuShowingChanged) { onMenuShowingChanged(isMenuShowing); @@ -203,6 +218,7 @@ export function ContextMenu({ const getClassName = getClassNamesFor('ContextMenu', moduleClassName); const optionElements = new Array(); + const isAnyOptionSelected = typeof value !== 'undefined'; for (const [index, option] of menuOptions.entries()) { const previous = menuOptions[index - 1]; @@ -229,6 +245,7 @@ export function ContextMenu({ closeCurrentOpenContextMenu = undefined; }; + const isOptionSelected = isAnyOptionSelected && value === option.value; optionElements.push( ); } @@ -291,18 +313,24 @@ export function ContextMenu({ let buttonNode: JSX.Element; if (typeof children === 'function') { - buttonNode = (children as (props: RenderButtonProps) => JSX.Element)({ - openMenu: onClick || handleClick, - onKeyDown: handleKeyDown, - isMenuShowing, - ref: setReferenceElement, - menuNode, - }); + buttonNode = ( + <> + {(children as (props: RenderButtonProps) => JSX.Element)({ + openMenu: onClick || handleClick, + onKeyDown: handleKeyDown, + isMenuShowing, + ref: setReferenceElement, + menuNode, + })} + {portalNode ? createPortal(menuNode, portalNode) : menuNode} + + ); } else { buttonNode = (
diff --git a/ts/components/ConversationList.stories.tsx b/ts/components/ConversationList.stories.tsx index c52db15d04..7422077a71 100644 --- a/ts/components/ConversationList.stories.tsx +++ b/ts/components/ConversationList.stories.tsx @@ -3,11 +3,10 @@ import React, { useContext } from 'react'; import { times, omit } from 'lodash'; - +import { v4 as generateUuid } from 'uuid'; import { action } from '@storybook/addon-actions'; -import { boolean, date, select, text } from '@storybook/addon-knobs'; - -import type { Row } from './ConversationList'; +import type { Meta } from '@storybook/react'; +import type { Row, PropsType } from './ConversationList'; import { ConversationList, RowType } from './ConversationList'; import { MessageSearchResult } from './conversationList/MessageSearchResult'; import type { PropsData as ConversationListItemPropsType } from './conversationList/ConversationListItem'; @@ -18,14 +17,15 @@ import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; import { ThemeType } from '../types/Util'; import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext'; -import { UUID } from '../types/UUID'; -import { makeFakeLookupConversationWithoutUuid } from '../test-both/helpers/fakeLookupConversationWithoutUuid'; +import { makeFakeLookupConversationWithoutServiceId } from '../test-both/helpers/fakeLookupConversationWithoutServiceId'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/ConversationList', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const defaultConversations: Array = [ getDefaultConversation({ @@ -95,7 +95,7 @@ function Wrapper({ /> )} scrollable={scrollable} - lookupConversationWithoutUuid={makeFakeLookupConversationWithoutUuid()} + lookupConversationWithoutServiceId={makeFakeLookupConversationWithoutServiceId()} showChooseGroupMembers={action('showChooseGroupMembers')} showUserNotFoundModal={action('showUserNotFoundModal')} setIsFetchingUUID={action('setIsFetchingUUID')} @@ -105,15 +105,13 @@ function Wrapper({ ); } -export const _ArchiveButton = (): JSX.Element => ( - -); - -_ArchiveButton.story = { - name: 'Archive button', -}; +export function ArchiveButton(): JSX.Element { + return ( + + ); +} export function ContactNoteToSelf(): JSX.Element { return ( @@ -132,10 +130,6 @@ export function ContactNoteToSelf(): JSX.Element { ); } -ContactNoteToSelf.story = { - name: 'Contact: note to self', -}; - export function ContactDirect(): JSX.Element { return ( = {} ): ConversationListItemPropsType => ({ ...overrideProps, - acceptedMessageRequest: boolean( - 'acceptedMessageRequest', + acceptedMessageRequest: overrideProps.acceptedMessageRequest !== undefined ? overrideProps.acceptedMessageRequest - : true - ), + : true, badges: [], - isMe: boolean('isMe', overrideProps.isMe || false), - avatarPath: text('avatarPath', overrideProps.avatarPath || ''), + isMe: overrideProps.isMe ?? false, + avatarPath: overrideProps.avatarPath ?? '', id: overrideProps.id || '', - isSelected: boolean('isSelected', overrideProps.isSelected || false), - title: text('title', overrideProps.title || 'Some Person'), + isSelected: overrideProps.isSelected ?? false, + title: overrideProps.title ?? 'Some Person', profileName: overrideProps.profileName || 'Some Person', type: overrideProps.type || 'direct', - markedUnread: boolean('markedUnread', overrideProps.markedUnread || false), + markedUnread: overrideProps.markedUnread ?? false, lastMessage: overrideProps.lastMessage || { - text: text('lastMessage.text', 'Hi there!'), - status: select( - 'status', - MessageStatuses.reduce((m, s) => ({ ...m, [s]: s }), {}), - 'read' - ), + text: 'Hi there!', + status: 'read', deletedForEveryone: false, }, - lastUpdated: date( - 'lastUpdated', - new Date(overrideProps.lastUpdated || Date.now() - 5 * 60 * 1000) - ), + lastUpdated: overrideProps.lastUpdated ?? Date.now() - 5 * 60 * 1000, sharedGroupNames: [], }); @@ -333,19 +290,11 @@ const renderConversation = ( export const ConversationName = (): JSX.Element => renderConversation(); -ConversationName.story = { - name: 'Conversation: name', -}; - export const ConversationNameAndAvatar = (): JSX.Element => renderConversation({ avatarPath: '/fixtures/kitten-1-64-64.jpg', }); -ConversationNameAndAvatar.story = { - name: 'Conversation: name and avatar', -}; - export const ConversationWithYourself = (): JSX.Element => renderConversation({ lastMessage: { @@ -358,10 +307,6 @@ export const ConversationWithYourself = (): JSX.Element => isMe: true, }); -ConversationWithYourself.story = { - name: 'Conversation: with yourself', -}; - export function ConversationsMessageStatuses(): JSX.Element { return ( renderConversation({ - typingContactId: UUID.generate().toString(), + typingContactIdTimestamps: { + [generateUuid()]: Date.now(), + }, }); -ConversationTypingStatus.story = { - name: 'Conversation: Typing Status', -}; - export const ConversationWithDraft = (): JSX.Element => renderConversation({ shouldShowDraft: true, @@ -398,19 +337,11 @@ export const ConversationWithDraft = (): JSX.Element => }, }); -ConversationWithDraft.story = { - name: 'Conversation: With draft', -}; - export const ConversationDeletedForEveryone = (): JSX.Element => renderConversation({ lastMessage: { deletedForEveryone: true }, }); -ConversationDeletedForEveryone.story = { - name: 'Conversation: Deleted for everyone', -}; - export const ConversationMessageRequest = (): JSX.Element => renderConversation({ acceptedMessageRequest: false, @@ -421,10 +352,6 @@ export const ConversationMessageRequest = (): JSX.Element => }, }); -ConversationMessageRequest.story = { - name: 'Conversation: Message Request', -}; - export function ConversationsUnreadCount(): JSX.Element { return ( renderConversation({ markedUnread: true }); -ConversationMarkedUnread.story = { - name: 'Conversation: marked unread', -}; - export const ConversationSelected = (): JSX.Element => renderConversation({ lastMessage: { @@ -464,10 +383,6 @@ export const ConversationSelected = (): JSX.Element => isSelected: true, }); -ConversationSelected.story = { - name: 'Conversation: Selected', -}; - export const ConversationEmojiInMessage = (): JSX.Element => renderConversation({ lastMessage: { @@ -477,10 +392,6 @@ export const ConversationEmojiInMessage = (): JSX.Element => }, }); -ConversationEmojiInMessage.story = { - name: 'Conversation: Emoji in Message', -}; - export const ConversationLinkInMessage = (): JSX.Element => renderConversation({ lastMessage: { @@ -490,10 +401,6 @@ export const ConversationLinkInMessage = (): JSX.Element => }, }); -ConversationLinkInMessage.story = { - name: 'Conversation: Link in Message', -}; - export const ConversationLongName = (): JSX.Element => { const name = 'Long contact name. Esquire. The third. And stuff. And more! And more!'; @@ -503,10 +410,6 @@ export const ConversationLongName = (): JSX.Element => { }); }; -ConversationLongName.story = { - name: 'Conversation: long name', -}; - export function ConversationLongMessage(): JSX.Element { const messages = [ "Long line. This is a really really really long line. Really really long. Because that's just how it is", @@ -532,10 +435,6 @@ Line 4, well.`, ); } -ConversationLongMessage.story = { - name: 'Conversation: Long Message', -}; - export function ConversationsVariousTimes(): JSX.Element { const pairs: Array<[number, string]> = [ [Date.now() - 5 * 60 * 60 * 1000, 'Five hours ago'], @@ -561,10 +460,6 @@ export function ConversationsVariousTimes(): JSX.Element { ); } -ConversationsVariousTimes.story = { - name: 'Conversations: Various Times', -}; - export function ConversationMissingDate(): JSX.Element { const row = { type: RowType.Conversation as const, @@ -574,10 +469,6 @@ export function ConversationMissingDate(): JSX.Element { return ; } -ConversationMissingDate.story = { - name: 'Conversation: Missing Date', -}; - export function ConversationMissingMessage(): JSX.Element { const row = { type: RowType.Conversation as const, @@ -587,10 +478,6 @@ export function ConversationMissingMessage(): JSX.Element { return ; } -ConversationMissingMessage.story = { - name: 'Conversation: Missing Message', -}; - export const ConversationMissingText = (): JSX.Element => renderConversation({ lastMessage: { @@ -600,19 +487,11 @@ export const ConversationMissingText = (): JSX.Element => }, }); -ConversationMissingText.story = { - name: 'Conversation: Missing Text', -}; - export const ConversationMutedConversation = (): JSX.Element => renderConversation({ muteExpiresAt: Date.now() + 1000 * 60 * 60, }); -ConversationMutedConversation.story = { - name: 'Conversation: Muted Conversation', -}; - export const ConversationAtMention = (): JSX.Element => renderConversation({ title: 'The Rebellion', @@ -624,10 +503,6 @@ export const ConversationAtMention = (): JSX.Element => }, }); -ConversationAtMention.story = { - name: 'Conversation: At Mention', -}; - export function Headers(): JSX.Element { return ( ); } - -KitchenSink.story = { - name: 'Kitchen sink', -}; diff --git a/ts/components/ConversationList.tsx b/ts/components/ConversationList.tsx index 2736512daf..50431a39b4 100644 --- a/ts/components/ConversationList.tsx +++ b/ts/components/ConversationList.tsx @@ -12,9 +12,9 @@ import { assertDev } from '../util/assert'; import type { ParsedE164Type } from '../util/libphonenumberInstance'; import type { LocalizerType, ThemeType } from '../types/Util'; import { ScrollBehavior } from '../types/Util'; -import { getConversationListWidthBreakpoint } from './_util'; +import { getNavSidebarWidthBreakpoint } from './_util'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; -import type { LookupConversationWithoutUuidActionsType } from '../util/lookupConversationWithoutUuid'; +import type { LookupConversationWithoutServiceIdActionsType } from '../util/lookupConversationWithoutServiceId'; import type { ShowConversationType } from '../state/ducks/conversations'; import type { PropsData as ConversationListItemPropsType } from './conversationList/ConversationListItem'; @@ -185,11 +185,11 @@ export type PropsType = { onSelectConversation: (conversationId: string, messageId?: string) => void; onOutgoingAudioCallInConversation: (conversationId: string) => void; onOutgoingVideoCallInConversation: (conversationId: string) => void; - removeConversation?: (conversationId: string) => void; + removeConversation: (conversationId: string) => void; renderMessageSearchResult?: (id: string) => JSX.Element; showChooseGroupMembers: () => void; showConversation: ShowConversationType; -} & LookupConversationWithoutUuidActionsType; +} & LookupConversationWithoutServiceIdActionsType; const NORMAL_ROW_HEIGHT = 76; const SELECT_ROW_HEIGHT = 52; @@ -214,7 +214,7 @@ export function ConversationList({ scrollable = true, shouldRecomputeRowHeights, showChooseGroupMembers, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, showConversation, @@ -313,7 +313,9 @@ export function ConversationList({ result = ( @@ -330,7 +332,9 @@ export function ConversationList({ result = ( @@ -366,11 +370,11 @@ export function ConversationList({ 'shouldShowDraft', 'title', 'type', - 'typingContactId', + 'typingContactIdTimestamps', 'unblurredAvatarPath', 'unreadCount', 'unreadMentionsCount', - 'uuid', + 'serviceId', ]); const { badges, title, unreadCount, lastMessage } = itemProps; result = ( @@ -436,7 +440,9 @@ export function ConversationList({ i18n={i18n} phoneNumber={row.phoneNumber} isFetching={row.isFetching} - lookupConversationWithoutUuid={lookupConversationWithoutUuid} + lookupConversationWithoutServiceId={ + lookupConversationWithoutServiceId + } showUserNotFoundModal={showUserNotFoundModal} setIsFetchingUUID={setIsFetchingUUID} showConversation={showConversation} @@ -449,7 +455,9 @@ export function ConversationList({ i18n={i18n} username={row.username} isFetchingUsername={row.isFetchingUsername} - lookupConversationWithoutUuid={lookupConversationWithoutUuid} + lookupConversationWithoutServiceId={ + lookupConversationWithoutServiceId + } showUserNotFoundModal={showUserNotFoundModal} setIsFetchingUUID={setIsFetchingUUID} showConversation={showConversation} @@ -473,7 +481,7 @@ export function ConversationList({ getPreferredBadge, getRow, i18n, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, onClickArchiveButton, onClickContactCheckbox, onOutgoingAudioCallInConversation, @@ -493,7 +501,7 @@ export function ConversationList({ return null; } - const widthBreakpoint = getConversationListWidthBreakpoint(dimensions.width); + const widthBreakpoint = getNavSidebarWidthBreakpoint(dimensions.width); return ( ; const i18n = setupI18n('en', enMessages); -export const _CrashReportDialog = (): JSX.Element => { +export function Basic(): JSX.Element { const [isPending, setIsPending] = useState(false); return ( @@ -31,8 +33,4 @@ export const _CrashReportDialog = (): JSX.Element => { eraseCrashReports={action('eraseCrashReports')} /> ); -}; - -_CrashReportDialog.story = { - name: 'CrashReportDialog', -}; +} diff --git a/ts/components/CrashReportDialog.tsx b/ts/components/CrashReportDialog.tsx index 28e73d56e2..4f20b62c3c 100644 --- a/ts/components/CrashReportDialog.tsx +++ b/ts/components/CrashReportDialog.tsx @@ -13,7 +13,7 @@ type PropsActionsType = { eraseCrashReports: () => void; }; -type PropsType = { +export type PropsType = { i18n: LocalizerType; isPending: boolean; } & PropsActionsType; diff --git a/ts/components/CustomColorEditor.stories.tsx b/ts/components/CustomColorEditor.stories.tsx index 173e7cc454..91beaaee45 100644 --- a/ts/components/CustomColorEditor.stories.tsx +++ b/ts/components/CustomColorEditor.stories.tsx @@ -5,6 +5,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import type { PropsType } from './CustomColorEditor'; import { CustomColorEditor } from './CustomColorEditor'; @@ -12,7 +13,7 @@ import { setupI18n } from '../util/setupI18n'; export default { title: 'Components/CustomColorEditor', -}; +} satisfies Meta; const i18n = setupI18n('en', enMessages); diff --git a/ts/components/CustomizingPreferredReactionsModal.stories.tsx b/ts/components/CustomizingPreferredReactionsModal.stories.tsx index 62a69bc677..23572eb2ca 100644 --- a/ts/components/CustomizingPreferredReactionsModal.stories.tsx +++ b/ts/components/CustomizingPreferredReactionsModal.stories.tsx @@ -5,16 +5,19 @@ import type { ComponentProps } from 'react'; import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; +import { DEFAULT_PREFERRED_REACTION_EMOJI } from '../reactions/constants'; import enMessages from '../../_locales/en/messages.json'; +import type { PropsType } from './CustomizingPreferredReactionsModal'; import { CustomizingPreferredReactionsModal } from './CustomizingPreferredReactionsModal'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/CustomizingPreferredReactionsModal', -}; +} satisfies Meta; const defaultProps: ComponentProps = { @@ -27,7 +30,7 @@ const defaultProps: ComponentProps = i18n, isSaving: false, onSetSkinTone: action('onSetSkinTone'), - originalPreferredReactions: ['❀', '👍', '👎', '😂', '😼', '😱'], + originalPreferredReactions: DEFAULT_PREFERRED_REACTION_EMOJI, recentEmojis: ['cake'], replaceSelectedDraftEmoji: action('replaceSelectedDraftEmoji'), resetDraftEmoji: action('resetDraftEmoji'), @@ -50,10 +53,6 @@ export function DraftEmojiSelected(): JSX.Element { ); } -DraftEmojiSelected.story = { - name: 'Draft emoji selected', -}; - export function Saving(): JSX.Element { return ; } @@ -61,7 +60,3 @@ export function Saving(): JSX.Element { export function HadError(): JSX.Element { return ; } - -HadError.story = { - name: 'Had error', -}; diff --git a/ts/components/CustomizingPreferredReactionsModal.tsx b/ts/components/CustomizingPreferredReactionsModal.tsx index ae50f9511b..073cc06ac6 100644 --- a/ts/components/CustomizingPreferredReactionsModal.tsx +++ b/ts/components/CustomizingPreferredReactionsModal.tsx @@ -19,7 +19,7 @@ import { convertShortName } from './emoji/lib'; import { offsetDistanceModifier } from '../util/popperUtil'; import { handleOutsideClick } from '../util/handleOutsideClick'; -type PropsType = { +export type PropsType = { draftPreferredReactions: ReadonlyArray; hadSaveError: boolean; i18n: LocalizerType; diff --git a/ts/components/DebugLogWindow.stories.tsx b/ts/components/DebugLogWindow.stories.tsx index 7118a5bbe8..2e226a0db0 100644 --- a/ts/components/DebugLogWindow.stories.tsx +++ b/ts/components/DebugLogWindow.stories.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import type { PropsType } from './DebugLogWindow'; import { DebugLogWindow } from './DebugLogWindow'; @@ -31,12 +32,8 @@ const createProps = (): PropsType => ({ export default { title: 'Components/DebugLogWindow', -}; +} satisfies Meta; -export const _DebugLogWindow = (): JSX.Element => ( - -); - -_DebugLogWindow.story = { - name: 'DebugLogWindow', -}; +export function Basic(): JSX.Element { + return ; +} diff --git a/ts/components/DeleteMessagesModal.tsx b/ts/components/DeleteMessagesModal.tsx index e12c248270..c967d6a8e7 100644 --- a/ts/components/DeleteMessagesModal.tsx +++ b/ts/components/DeleteMessagesModal.tsx @@ -41,7 +41,7 @@ export default function DeleteMessagesModal({ : i18n('icu:DeleteMessagesModal--deleteForMe'), }); - if (canDeleteForEveryone) { + if (canDeleteForEveryone || isMe) { const tooManyMessages = messageCount > MAX_DELETE_FOR_EVERYONE; actions.push({ 'aria-disabled': tooManyMessages, diff --git a/ts/components/DialogExpiredBuild.stories.tsx b/ts/components/DialogExpiredBuild.stories.tsx index 11df133f0a..2d8b732e63 100644 --- a/ts/components/DialogExpiredBuild.stories.tsx +++ b/ts/components/DialogExpiredBuild.stories.tsx @@ -2,8 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { select } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './DialogExpiredBuild'; import { DialogExpiredBuild } from './DialogExpiredBuild'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -14,14 +14,12 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/DialogExpiredBuild', -}; + argTypes: {}, + args: {}, +} satisfies Meta; -export const _DialogExpiredBuild = (): JSX.Element => { - const containerWidthBreakpoint = select( - 'containerWidthBreakpoint', - WidthBreakpoint, - WidthBreakpoint.Wide - ); +export function Basic(): JSX.Element { + const containerWidthBreakpoint = WidthBreakpoint.Wide; return ( @@ -31,8 +29,4 @@ export const _DialogExpiredBuild = (): JSX.Element => { /> ); -}; - -_DialogExpiredBuild.story = { - name: 'DialogExpiredBuild', -}; +} diff --git a/ts/components/DialogNetworkStatus.stories.tsx b/ts/components/DialogNetworkStatus.stories.tsx index 9bcf717e1a..cfbec3cc14 100644 --- a/ts/components/DialogNetworkStatus.stories.tsx +++ b/ts/components/DialogNetworkStatus.stories.tsx @@ -4,6 +4,7 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './DialogNetworkStatus'; import { DialogNetworkStatus } from './DialogNetworkStatus'; import { SocketStatus } from '../types/SocketStatus'; @@ -27,7 +28,7 @@ const defaultProps = { export default { title: 'Components/DialogNetworkStatus', -}; +} satisfies Meta; export function KnobsPlayground(args: PropsType): JSX.Element { /* @@ -68,10 +69,6 @@ export function ConnectingWide(): JSX.Element { ); } -ConnectingWide.story = { - name: 'Connecting Wide', -}; - export function ClosingWide(): JSX.Element { return ( @@ -84,10 +81,6 @@ export function ClosingWide(): JSX.Element { ); } -ClosingWide.story = { - name: 'Closing Wide', -}; - export function ClosedWide(): JSX.Element { return ( @@ -100,10 +93,6 @@ export function ClosedWide(): JSX.Element { ); } -ClosedWide.story = { - name: 'Closed Wide', -}; - export function OfflineWide(): JSX.Element { return ( @@ -116,10 +105,6 @@ export function OfflineWide(): JSX.Element { ); } -OfflineWide.story = { - name: 'Offline Wide', -}; - export function ConnectingNarrow(): JSX.Element { return ( @@ -132,10 +117,6 @@ export function ConnectingNarrow(): JSX.Element { ); } -ConnectingNarrow.story = { - name: 'Connecting Narrow', -}; - export function ClosingNarrow(): JSX.Element { return ( @@ -148,10 +129,6 @@ export function ClosingNarrow(): JSX.Element { ); } -ClosingNarrow.story = { - name: 'Closing Narrow', -}; - export function ClosedNarrow(): JSX.Element { return ( @@ -164,10 +141,6 @@ export function ClosedNarrow(): JSX.Element { ); } -ClosedNarrow.story = { - name: 'Closed Narrow', -}; - export function OfflineNarrow(): JSX.Element { return ( @@ -179,7 +152,3 @@ export function OfflineNarrow(): JSX.Element { ); } - -OfflineNarrow.story = { - name: 'Offline Narrow', -}; diff --git a/ts/components/DialogRelink.stories.tsx b/ts/components/DialogRelink.stories.tsx index 813da6e456..01ab3e7fcb 100644 --- a/ts/components/DialogRelink.stories.tsx +++ b/ts/components/DialogRelink.stories.tsx @@ -3,7 +3,8 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './DialogRelink'; import { DialogRelink } from './DialogRelink'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -35,7 +36,7 @@ const permutations = [ export default { title: 'Components/DialogRelink', -}; +} satisfies Meta; export function Iterations(): JSX.Element { return ( diff --git a/ts/components/DialogUpdate.stories.tsx b/ts/components/DialogUpdate.stories.tsx index 4e202cd5f9..097206d812 100644 --- a/ts/components/DialogUpdate.stories.tsx +++ b/ts/components/DialogUpdate.stories.tsx @@ -2,8 +2,9 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { select } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './DialogUpdate'; import { DialogUpdate } from './DialogUpdate'; import { DialogType } from '../types/Dialogs'; import { WidthBreakpoint } from './_util'; @@ -29,15 +30,13 @@ const defaultProps = { export default { title: 'Components/DialogUpdate', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function KnobsPlayground(): JSX.Element { - const containerWidthBreakpoint = select( - 'containerWidthBreakpoint', - WidthBreakpoint, - WidthBreakpoint.Wide - ); - const dialogType = select('dialogType', DialogType, DialogType.AutoUpdate); + const containerWidthBreakpoint = WidthBreakpoint.Wide; + const dialogType = DialogType.AutoUpdate; return ( @@ -64,10 +63,6 @@ export function UpdateWide(): JSX.Element { ); } -UpdateWide.story = { - name: 'Update (Wide)', -}; - export function DownloadedWide(): JSX.Element { return ( @@ -81,10 +76,6 @@ export function DownloadedWide(): JSX.Element { ); } -DownloadedWide.story = { - name: 'Downloaded (Wide)', -}; - export function DownloadReadyWide(): JSX.Element { return ( @@ -99,10 +90,6 @@ export function DownloadReadyWide(): JSX.Element { ); } -DownloadReadyWide.story = { - name: 'DownloadReady (Wide)', -}; - export function FullDownloadReadyWide(): JSX.Element { return ( @@ -117,10 +104,6 @@ export function FullDownloadReadyWide(): JSX.Element { ); } -FullDownloadReadyWide.story = { - name: 'FullDownloadReady (Wide)', -}; - export function DownloadingWide(): JSX.Element { const [downloadedSize, setDownloadedSize] = React.useState(0); @@ -153,10 +136,6 @@ export function DownloadingWide(): JSX.Element { ); } -DownloadingWide.story = { - name: 'Downloading (Wide)', -}; - export function CannotUpdateWide(): JSX.Element { return ( @@ -170,10 +149,6 @@ export function CannotUpdateWide(): JSX.Element { ); } -CannotUpdateWide.story = { - name: 'Cannot_Update (Wide)', -}; - export function CannotUpdateBetaWide(): JSX.Element { return ( @@ -187,10 +162,6 @@ export function CannotUpdateBetaWide(): JSX.Element { ); } -CannotUpdateBetaWide.story = { - name: 'Cannot_Update_Beta (Wide)', -}; - export function CannotUpdateRequireManualWide(): JSX.Element { return ( @@ -204,10 +175,6 @@ export function CannotUpdateRequireManualWide(): JSX.Element { ); } -CannotUpdateRequireManualWide.story = { - name: 'Cannot_Update_Require_Manual (Wide)', -}; - export function CannotUpdateRequireManualBetaWide(): JSX.Element { return ( @@ -221,10 +188,6 @@ export function CannotUpdateRequireManualBetaWide(): JSX.Element { ); } -CannotUpdateRequireManualBetaWide.story = { - name: 'Cannot_Update_Require_Manual_Beta (Wide)', -}; - export function MacOSReadOnlyWide(): JSX.Element { return ( @@ -238,10 +201,6 @@ export function MacOSReadOnlyWide(): JSX.Element { ); } -MacOSReadOnlyWide.story = { - name: 'MacOS_Read_Only (Wide)', -}; - export function UnsupportedOSWide(): JSX.Element { return ( @@ -255,10 +214,6 @@ export function UnsupportedOSWide(): JSX.Element { ); } -UnsupportedOSWide.story = { - name: 'UnsupportedOS (Wide)', -}; - export function UpdateNarrow(): JSX.Element { return ( @@ -272,10 +227,6 @@ export function UpdateNarrow(): JSX.Element { ); } -UpdateNarrow.story = { - name: 'Update (Narrow)', -}; - export function DownloadedNarrow(): JSX.Element { return ( @@ -289,10 +240,6 @@ export function DownloadedNarrow(): JSX.Element { ); } -DownloadedNarrow.story = { - name: 'Downloaded (Narrow)', -}; - export function DownloadReadyNarrow(): JSX.Element { return ( @@ -307,10 +254,6 @@ export function DownloadReadyNarrow(): JSX.Element { ); } -DownloadReadyNarrow.story = { - name: 'DownloadReady (Narrow)', -}; - export function FullDownloadReadyNarrow(): JSX.Element { return ( @@ -325,10 +268,6 @@ export function FullDownloadReadyNarrow(): JSX.Element { ); } -FullDownloadReadyNarrow.story = { - name: 'FullDownloadReady (Narrow)', -}; - export function DownloadingNarrow(): JSX.Element { return ( @@ -342,10 +281,6 @@ export function DownloadingNarrow(): JSX.Element { ); } -DownloadingNarrow.story = { - name: 'Downloading (Narrow)', -}; - export function CannotUpdateNarrow(): JSX.Element { return ( @@ -359,10 +294,6 @@ export function CannotUpdateNarrow(): JSX.Element { ); } -CannotUpdateNarrow.story = { - name: 'Cannot Update (Narrow)', -}; - export function CannotUpdateBetaNarrow(): JSX.Element { return ( @@ -376,10 +307,6 @@ export function CannotUpdateBetaNarrow(): JSX.Element { ); } -CannotUpdateBetaNarrow.story = { - name: 'Cannot Update Beta (Narrow)', -}; - export function CannotUpdateRequireManualNarrow(): JSX.Element { return ( @@ -393,10 +320,6 @@ export function CannotUpdateRequireManualNarrow(): JSX.Element { ); } -CannotUpdateRequireManualNarrow.story = { - name: 'Cannot_Update_Require_Manual (Narrow)', -}; - export function CannotUpdateRequireManualBetaNarrow(): JSX.Element { return ( @@ -410,10 +333,6 @@ export function CannotUpdateRequireManualBetaNarrow(): JSX.Element { ); } -CannotUpdateRequireManualBetaNarrow.story = { - name: 'Cannot_Update_Require_Manual_Beta (Narrow)', -}; - export function MacOSReadOnlyNarrow(): JSX.Element { return ( @@ -427,10 +346,6 @@ export function MacOSReadOnlyNarrow(): JSX.Element { ); } -MacOSReadOnlyNarrow.story = { - name: 'MacOS_Read_Only (Narrow)', -}; - export function UnsupportedOSNarrow(): JSX.Element { return ( @@ -443,7 +358,3 @@ export function UnsupportedOSNarrow(): JSX.Element { ); } - -UnsupportedOSNarrow.story = { - name: 'UnsupportedOS (Narrow)', -}; diff --git a/ts/components/DirectCallRemoteParticipant.tsx b/ts/components/DirectCallRemoteParticipant.tsx index edc51e5d4b..8006ed8ce7 100644 --- a/ts/components/DirectCallRemoteParticipant.tsx +++ b/ts/components/DirectCallRemoteParticipant.tsx @@ -2,16 +2,19 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useRef, useEffect } from 'react'; +import classNames from 'classnames'; import type { SetRendererCanvasType } from '../state/ducks/calling'; import type { ConversationType } from '../state/ducks/conversations'; import type { LocalizerType } from '../types/Util'; import { AvatarColors } from '../types/Colors'; import { Avatar, AvatarSize } from './Avatar'; +import { CallBackgroundBlur } from './CallBackgroundBlur'; type PropsType = { conversation: ConversationType; hasRemoteVideo: boolean; i18n: LocalizerType; + isReconnecting: boolean; setRendererCanvas: (_: SetRendererCanvasType) => void; }; @@ -19,6 +22,7 @@ export function DirectCallRemoteParticipant({ conversation, hasRemoteVideo, i18n, + isReconnecting, setRendererCanvas, }: PropsType): JSX.Element { const remoteVideoRef = useRef(null); @@ -32,7 +36,11 @@ export function DirectCallRemoteParticipant({ return hasRemoteVideo ? ( ) : ( @@ -65,21 +73,23 @@ function renderAvatar( ): JSX.Element { return (
- + + +
); } diff --git a/ts/components/DisappearingTimeDialog.stories.tsx b/ts/components/DisappearingTimeDialog.stories.tsx index 3ed55aa89a..69a99e1157 100644 --- a/ts/components/DisappearingTimeDialog.stories.tsx +++ b/ts/components/DisappearingTimeDialog.stories.tsx @@ -3,7 +3,8 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './DisappearingTimeDialog'; import { DisappearingTimeDialog } from './DisappearingTimeDialog'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -12,7 +13,7 @@ import { EXPIRE_TIMERS } from '../test-both/util/expireTimers'; export default { title: 'Components/DisappearingTimeDialog', -}; +} satisfies Meta; const i18n = setupI18n('en', enMessages); diff --git a/ts/components/DisappearingTimerSelect.stories.tsx b/ts/components/DisappearingTimerSelect.stories.tsx index 11d8973f0c..460abf1d6f 100644 --- a/ts/components/DisappearingTimerSelect.stories.tsx +++ b/ts/components/DisappearingTimerSelect.stories.tsx @@ -2,7 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState } from 'react'; - +import type { Meta } from '@storybook/react'; +import type { Props } from './DisappearingTimerSelect'; import { DisappearingTimerSelect } from './DisappearingTimerSelect'; import { setupI18n } from '../util/setupI18n'; import { DurationInSeconds } from '../util/durations'; @@ -10,15 +11,15 @@ import enMessages from '../../_locales/en/messages.json'; export default { title: 'Components/DisappearingTimerSelect', -}; +} satisfies Meta; const i18n = setupI18n('en', enMessages); -type Props = { +type Args = { initialValue: number; }; -function TimerSelectWrap({ initialValue }: Props): JSX.Element { +function TimerSelectWrap({ initialValue }: Args): JSX.Element { const [value, setValue] = useState(initialValue); return ( @@ -34,14 +35,6 @@ export function InitialValue1Day(): JSX.Element { return ; } -InitialValue1Day.story = { - name: 'Initial value: 1 day', -}; - export function InitialValue3DaysCustomTime(): JSX.Element { return ; } - -InitialValue3DaysCustomTime.story = { - name: 'Initial value 3 days (Custom time)', -}; diff --git a/ts/components/EditUsernameModalBody.stories.tsx b/ts/components/EditUsernameModalBody.stories.tsx index 1e9fed1539..92a9db4885 100644 --- a/ts/components/EditUsernameModalBody.stories.tsx +++ b/ts/components/EditUsernameModalBody.stories.tsx @@ -2,8 +2,9 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; import enMessages from '../../_locales/en/messages.json'; import { setupI18n } from '../util/setupI18n'; import type { UsernameReservationType } from '../types/Username'; @@ -29,11 +30,9 @@ export default { argTypes: { currentUsername: { type: { name: 'string', required: false }, - defaultValue: undefined, }, state: { control: { type: 'radio' }, - defaultValue: State.Open, options: { Open: State.Open, Closed: State.Closed, @@ -43,7 +42,6 @@ export default { }, error: { control: { type: 'radio' }, - defaultValue: undefined, options: { None: undefined, NotEnoughCharacters: UsernameReservationError.NotEnoughCharacters, @@ -54,26 +52,24 @@ export default { General: UsernameReservationError.General, }, }, - maxUsername: { - defaultValue: 20, - }, - minUsername: { - defaultValue: 3, - }, - discriminator: { + reservation: { type: { name: 'string', required: false }, - defaultValue: undefined, }, - i18n: { - defaultValue: i18n, - }, - onClose: { action: true }, - onError: { action: true }, - setUsernameReservationError: { action: true }, - reserveUsername: { action: true }, - confirmUsername: { action: true }, }, -} as Meta; + args: { + currentUsername: undefined, + state: State.Open, + error: undefined, + maxNickname: 20, + minNickname: 3, + reservation: undefined, + i18n, + onClose: action('onClose'), + setUsernameReservationError: action('setUsernameReservationError'), + reserveUsername: action('reserveUsername'), + confirmUsername: action('confirmUsername'), + }, +} satisfies Meta; type ArgsType = PropsType & { discriminator?: string; @@ -81,7 +77,7 @@ type ArgsType = PropsType & { }; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => { +const Template: StoryFn = args => { let { reservation } = args; if (!reservation && args.discriminator) { reservation = { @@ -95,27 +91,16 @@ const Template: Story = args => { export const WithoutUsername = Template.bind({}); WithoutUsername.args = {}; -WithoutUsername.story = { - name: 'without current username', -}; export const WithUsername = Template.bind({}); -WithUsername.args = {}; -WithUsername.story = { - name: 'with current username', - args: { - currentUsername: 'signaluser.12', - }, +WithUsername.args = { + currentUsername: 'signaluser.12', }; export const WithReservation = Template.bind({}); -WithReservation.args = {}; -WithReservation.story = { - name: 'with reservation', - args: { - currentUsername: 'reserved', - reservation: DEFAULT_RESERVATION, - }, +WithReservation.args = { + currentUsername: 'reserved', + reservation: DEFAULT_RESERVATION, }; export const UsernameEditingConfirming = Template.bind({}); @@ -123,9 +108,6 @@ UsernameEditingConfirming.args = { state: State.Confirming, currentUsername: 'signaluser.12', }; -UsernameEditingConfirming.story = { - name: 'Username editing, Confirming', -}; export const UsernameEditingUsernameTaken = Template.bind({}); UsernameEditingUsernameTaken.args = { @@ -133,9 +115,6 @@ UsernameEditingUsernameTaken.args = { error: UsernameReservationError.UsernameNotAvailable, currentUsername: 'signaluser.12', }; -UsernameEditingUsernameTaken.story = { - name: 'Username editing, username taken', -}; export const UsernameEditingUsernameWrongCharacters = Template.bind({}); UsernameEditingUsernameWrongCharacters.args = { @@ -143,9 +122,6 @@ UsernameEditingUsernameWrongCharacters.args = { error: UsernameReservationError.CheckCharacters, currentUsername: 'signaluser.12', }; -UsernameEditingUsernameWrongCharacters.story = { - name: 'Username editing, Wrong Characters', -}; export const UsernameEditingUsernameTooShort = Template.bind({}); UsernameEditingUsernameTooShort.args = { @@ -153,9 +129,6 @@ UsernameEditingUsernameTooShort.args = { error: UsernameReservationError.NotEnoughCharacters, currentUsername: 'sig', }; -UsernameEditingUsernameTooShort.story = { - name: 'Username editing, username too short', -}; export const UsernameEditingGeneralError = Template.bind({}); UsernameEditingGeneralError.args = { @@ -163,6 +136,3 @@ UsernameEditingGeneralError.args = { error: UsernameReservationError.General, currentUsername: 'signaluser.12', }; -UsernameEditingGeneralError.story = { - name: 'Username editing, general error', -}; diff --git a/ts/components/ErrorModal.stories.tsx b/ts/components/ErrorModal.stories.tsx index 51a3d40b7a..20775c3187 100644 --- a/ts/components/ErrorModal.stories.tsx +++ b/ts/components/ErrorModal.stories.tsx @@ -2,9 +2,9 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { text } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './ErrorModal'; import { ErrorModal } from './ErrorModal'; @@ -14,15 +14,17 @@ import enMessages from '../../_locales/en/messages.json'; const i18n = setupI18n('en', enMessages); const createProps = (overrideProps: Partial = {}): PropsType => ({ - title: text('title', overrideProps.title || ''), - description: text('description', overrideProps.description || ''), + title: overrideProps.title ?? '', + description: overrideProps.description ?? '', i18n, onClose: action('onClick'), }); export default { title: 'Components/ErrorModal', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function Normal(): JSX.Element { return ; diff --git a/ts/components/ForwardMessagesModal.stories.tsx b/ts/components/ForwardMessagesModal.stories.tsx index 0cf043ed2d..a078f4a4ae 100644 --- a/ts/components/ForwardMessagesModal.stories.tsx +++ b/ts/components/ForwardMessagesModal.stories.tsx @@ -2,10 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; -import { text } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import type { AttachmentType } from '../types/Attachment'; import type { PropsType } from './ForwardMessagesModal'; @@ -15,25 +13,25 @@ import { getDefaultConversation } from '../test-both/helpers/getDefaultConversat import { setupI18n } from '../util/setupI18n'; import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext'; import { CompositionTextArea } from './CompositionTextArea'; -import type { MessageForwardDraft } from '../util/maybeForwardMessages'; +import type { MessageForwardDraft } from '../types/ForwardDraft'; const createAttachment = ( props: Partial = {} ): AttachmentType => ({ pending: false, path: 'fileName.jpg', - contentType: stringToMIMEType( - text('attachment contentType', props.contentType || '') - ), - fileName: text('attachment fileName', props.fileName || ''), + contentType: stringToMIMEType(props.contentType ?? ''), + fileName: props.fileName ?? '', screenshotPath: props.pending === false ? props.screenshotPath : undefined, - url: text('attachment url', props.pending === false ? props.url || '' : ''), + url: props.pending === false ? props.url ?? '' : '', size: 3433, }); export default { title: 'Components/ForwardMessageModal', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const i18n = setupI18n('en', enMessages); @@ -82,7 +80,7 @@ function getMessageForwardDraft( attachments: overrideProps.attachments, hasContact: Boolean(overrideProps.hasContact), isSticker: Boolean(overrideProps.isSticker), - messageBody: text('messageBody', overrideProps.messageBody || ''), + messageBody: overrideProps.messageBody ?? '', originalMessageId: '123', previews: overrideProps.previews ?? [], }; @@ -102,10 +100,6 @@ export function WithText(): JSX.Element { ); } -WithText.story = { - name: 'with text', -}; - export function ASticker(): JSX.Element { return ( ); } - -AnnouncementOnlyGroupsNonAdmin.story = { - name: 'announcement only groups non-admin', -}; diff --git a/ts/components/ForwardMessagesModal.tsx b/ts/components/ForwardMessagesModal.tsx index bb3babb719..9ecef2f450 100644 --- a/ts/components/ForwardMessagesModal.tsx +++ b/ts/components/ForwardMessagesModal.tsx @@ -27,20 +27,20 @@ import { shouldNeverBeCalled, asyncShouldNeverBeCalled, } from '../util/shouldNeverBeCalled'; -import type { MessageForwardDraft } from '../util/maybeForwardMessages'; -import { - isDraftEditable, - isDraftForwardable, -} from '../util/maybeForwardMessages'; import type { LinkPreviewType } from '../types/message/LinkPreviews'; import { LinkPreviewSourceType } from '../types/LinkPreview'; import { ToastType } from '../types/Toast'; import type { ShowToastAction } from '../state/ducks/toast'; import type { HydratedBodyRangesType } from '../types/BodyRange'; -import { BodyRange } from '../types/BodyRange'; +import { applyRangesToText } from '../types/BodyRange'; import { UserText } from './UserText'; import { Modal } from './Modal'; import { SizeObserver } from '../hooks/useSizeObserver'; +import { + isDraftEditable, + isDraftForwardable, + type MessageForwardDraft, +} from '../types/ForwardDraft'; export type DataPropsType = { candidateConversations: ReadonlyArray; @@ -135,11 +135,25 @@ export function ForwardMessagesModal({ } else { doForwardMessages( conversationIds, - drafts.map(draft => ({ - ...draft, + drafts.map(draft => { // We don't keep @mention bodyRanges in multi-forward scenarios - bodyRanges: draft.bodyRanges?.filter(BodyRange.isFormatting), - })) + const result = applyRangesToText( + { + body: draft.messageBody ?? '', + bodyRanges: draft.bodyRanges ?? [], + }, + { + replaceMentions: true, + replaceSpoilers: false, + } + ); + + return { + ...draft, + messageBody: result.body, + bodyRanges: result.bodyRanges, + }; + }) ); } }, [ @@ -358,7 +372,9 @@ export function ForwardMessagesModal({ toggleSelectedConversation(conversationId); } }} - lookupConversationWithoutUuid={asyncShouldNeverBeCalled} + lookupConversationWithoutServiceId={ + asyncShouldNeverBeCalled + } showConversation={shouldNeverBeCalled} showUserNotFoundModal={shouldNeverBeCalled} setIsFetchingUUID={shouldNeverBeCalled} diff --git a/ts/components/GroupCallOverflowArea.stories.tsx b/ts/components/GroupCallOverflowArea.stories.tsx index 2640282eb0..42bf75c735 100644 --- a/ts/components/GroupCallOverflowArea.stories.tsx +++ b/ts/components/GroupCallOverflowArea.stories.tsx @@ -3,28 +3,31 @@ import React from 'react'; import { memoize, times } from 'lodash'; -import { number } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './GroupCallOverflowArea'; import { GroupCallOverflowArea } from './GroupCallOverflowArea'; import { setupI18n } from '../util/setupI18n'; -import { getDefaultConversationWithUuid } from '../test-both/helpers/getDefaultConversation'; +import { getDefaultConversationWithServiceId } from '../test-both/helpers/getDefaultConversation'; import { fakeGetGroupCallVideoFrameSource } from '../test-both/helpers/fakeGetGroupCallVideoFrameSource'; import { FRAME_BUFFER_SIZE } from '../calling/constants'; import enMessages from '../../_locales/en/messages.json'; +import { generateAci } from '../types/ServiceId'; const MAX_PARTICIPANTS = 32; const i18n = setupI18n('en', enMessages); const allRemoteParticipants = times(MAX_PARTICIPANTS).map(index => ({ + aci: generateAci(), demuxId: index, hasRemoteAudio: index % 3 !== 0, hasRemoteVideo: index % 4 !== 0, + isHandRaised: (index - 2) % 8 === 0, presenting: false, sharingScreen: false, videoAspectRatio: 1.3, - ...getDefaultConversationWithUuid({ + ...getDefaultConversationWithServiceId({ isBlocked: index === 10 || index === MAX_PARTICIPANTS - 1, title: `Participant ${index + 1}`, }), @@ -32,12 +35,15 @@ const allRemoteParticipants = times(MAX_PARTICIPANTS).map(index => ({ export default { title: 'Components/GroupCallOverflowArea', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const defaultProps = { getFrameBuffer: memoize(() => Buffer.alloc(FRAME_BUFFER_SIZE)), getGroupCallVideoFrameSource: fakeGetGroupCallVideoFrameSource, i18n, + isCallReconnecting: false, onParticipantVisibilityChanged: action('onParticipantVisibilityChanged'), remoteAudioLevels: new Map(), remoteParticipantsCount: 1, @@ -66,10 +72,6 @@ export function NoOverflowedParticipants(): JSX.Element { ); } -NoOverflowedParticipants.story = { - name: 'No overflowed participants', -}; - export function OneOverflowedParticipant(): JSX.Element { return ( @@ -81,10 +83,6 @@ export function OneOverflowedParticipant(): JSX.Element { ); } -OneOverflowedParticipant.story = { - name: 'One overflowed participant', -}; - export function ThreeOverflowedParticipants(): JSX.Element { return ( @@ -96,10 +94,6 @@ export function ThreeOverflowedParticipants(): JSX.Element { ); } -ThreeOverflowedParticipants.story = { - name: 'Three overflowed participants', -}; - export function ManyOverflowedParticipants(): JSX.Element { return ( @@ -107,18 +101,9 @@ export function ManyOverflowedParticipants(): JSX.Element { {...defaultProps} overflowedParticipants={allRemoteParticipants.slice( 0, - number('Participant count', MAX_PARTICIPANTS, { - range: true, - min: 0, - max: MAX_PARTICIPANTS, - step: 1, - }) + MAX_PARTICIPANTS )} /> ); } - -ManyOverflowedParticipants.story = { - name: 'Many overflowed participants', -}; diff --git a/ts/components/GroupCallOverflowArea.tsx b/ts/components/GroupCallOverflowArea.tsx index b60a135e0b..fcac255688 100644 --- a/ts/components/GroupCallOverflowArea.tsx +++ b/ts/components/GroupCallOverflowArea.tsx @@ -13,12 +13,13 @@ const OVERFLOW_SCROLLED_TO_EDGE_THRESHOLD = 20; const OVERFLOW_SCROLL_BUTTON_RATIO = 0.75; // This should be an integer, as sub-pixel widths can cause performance issues. -export const OVERFLOW_PARTICIPANT_WIDTH = 140; +export const OVERFLOW_PARTICIPANT_WIDTH = 107; -type PropsType = { +export type PropsType = { getFrameBuffer: () => Buffer; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; i18n: LocalizerType; + isCallReconnecting: boolean; onParticipantVisibilityChanged: ( demuxId: number, isVisible: boolean @@ -32,6 +33,7 @@ export function GroupCallOverflowArea({ getFrameBuffer, getGroupCallVideoFrameSource, i18n, + isCallReconnecting, onParticipantVisibilityChanged, overflowedParticipants, remoteAudioLevels, @@ -127,6 +129,7 @@ export function GroupCallOverflowArea({ remoteParticipant={remoteParticipant} remoteParticipantsCount={remoteParticipantsCount} isActiveSpeakerInSpeakerView={false} + isCallReconnecting={isCallReconnecting} /> ))}
diff --git a/ts/components/GroupCallRemoteParticipant.stories.tsx b/ts/components/GroupCallRemoteParticipant.stories.tsx index 92bcf3735c..507a797a6b 100644 --- a/ts/components/GroupCallRemoteParticipant.stories.tsx +++ b/ts/components/GroupCallRemoteParticipant.stories.tsx @@ -2,14 +2,14 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { memoize, noop } from 'lodash'; -import { select } from '@storybook/addon-knobs'; - +import { memoize } from 'lodash'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './GroupCallRemoteParticipant'; import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import { FRAME_BUFFER_SIZE } from '../calling/constants'; import { setupI18n } from '../util/setupI18n'; +import { generateAci } from '../types/ServiceId'; import enMessages from '../../_locales/en/messages.json'; const i18n = setupI18n('en', enMessages); @@ -38,21 +38,26 @@ const createProps = ( isBlocked = false, hasRemoteAudio = false, presenting = false, + isHandRaised = false, }: { isBlocked?: boolean; hasRemoteAudio?: boolean; presenting?: boolean; + isHandRaised?: boolean; } = {} ): PropsType => ({ getFrameBuffer, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - getGroupCallVideoFrameSource: noop as any, + getGroupCallVideoFrameSource: () => { + return { receiveVideoFrame: () => undefined }; + }, i18n, audioLevel: 0, remoteParticipant: { + aci: generateAci(), demuxId: 123, hasRemoteAudio, hasRemoteVideo: true, + isHandRaised, presenting, sharingScreen: false, videoAspectRatio: 1.3, @@ -60,17 +65,20 @@ const createProps = ( isBlocked: Boolean(isBlocked), title: 'Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso', - uuid: '992ed3b9-fc9b-47a9-bdb4-e0c7cbb0fda5', + serviceId: generateAci(), }), }, remoteParticipantsCount: 1, isActiveSpeakerInSpeakerView: false, + isCallReconnecting: false, ...overrideProps, }); export default { title: 'Components/GroupCallRemoteParticipant', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function Default(): JSX.Element { return ( @@ -99,7 +107,7 @@ export function Speaking(): JSX.Element { left: (120 + 10) * index, top: 0, width: 120, - audioLevel: select('audioLevel', [0, 0.5, 1], 0.5), + audioLevel: 0.5, remoteParticipantsCount, }, { hasRemoteAudio: true, presenting } @@ -114,6 +122,23 @@ export function Speaking(): JSX.Element { ); } +export function HandRaised(): JSX.Element { + return ( + + ); +} + export function IsInPip(): JSX.Element { return ( VideoFrameSource; i18n: LocalizerType; isActiveSpeakerInSpeakerView: boolean; + isCallReconnecting: boolean; onVisibilityChanged?: (demuxId: number, isVisible: boolean) => unknown; remoteParticipant: GroupCallRemoteParticipantType; remoteParticipantsCount: number; @@ -69,6 +70,7 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( onVisibilityChanged, remoteParticipantsCount, isActiveSpeakerInSpeakerView, + isCallReconnecting, } = props; const { @@ -78,6 +80,7 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( demuxId, hasRemoteAudio, hasRemoteVideo, + isHandRaised, isBlocked, isMe, profileName, @@ -136,7 +139,13 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( ? MAX_TIME_TO_SHOW_STALE_SCREENSHARE_FRAMES : MAX_TIME_TO_SHOW_STALE_VIDEO_FRAMES; if (frameAge > maxFrameAge) { - setHasReceivedVideoRecently(false); + // We consider that we have received video recently from a remote participant if + // we have received it recently relative to the last time we had a connection. If + // we lost their video due to our reconnecting, we still want to show the last + // frame of video (blurred out) until we have reconnected. + if (!isCallReconnecting) { + setHasReceivedVideoRecently(false); + } } const canvasEl = remoteVideoRef.current; @@ -191,7 +200,7 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( setHasReceivedVideoRecently(true); setIsWide(frameWidth > frameHeight); - }, [getFrameBuffer, videoFrameSource, sharingScreen]); + }, [getFrameBuffer, videoFrameSource, sharingScreen, isCallReconnecting]); useEffect(() => { if (!hasRemoteVideo) { @@ -250,7 +259,8 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( if ('top' in props) { containerStyles.position = 'absolute'; - containerStyles.transform = `translate(${props.left}px, ${props.top}px)`; + containerStyles.insetInlineStart = `${props.left}px`; + containerStyles.top = `${props.top}px`; } } @@ -286,31 +296,40 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( isSpeaking && !isActiveSpeakerInSpeakerView && remoteParticipantsCount > 1 && - 'module-ongoing-call__group-call-remote-participant--speaking' + 'module-ongoing-call__group-call-remote-participant--speaking', + isHandRaised && + 'module-ongoing-call__group-call-remote-participant--hand-raised' )} ref={intersectionRef} style={containerStyles} > {!props.isInPip && ( -
- + <> -
+
+
+ {isHandRaised && ( +
+ )} + +
+
+ )} {wantsToShowVideo && ( >; + rows: Array>; scalar: number; }; +type PaginationButtonType = { + isPaginationButton: true; + videoAspectRatio: number; + paginationButtonType: 'prev' | 'next'; + numParticipants: number; +}; +type ParticipantTileType = + | GroupCallRemoteParticipantType + | PaginationButtonType; type PropsType = { + callViewMode: CallViewMode; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; i18n: LocalizerType; - isInSpeakerView: boolean; + isCallReconnecting: boolean; remoteParticipants: ReadonlyArray; setGroupCallVideoRequest: ( _: Array, @@ -71,36 +85,43 @@ enum VideoRequestMode { // * Participants are arranged in 0 or more rows. // * Each row is the same height, but each participant may have a different width. // * It's possible, on small screens with lots of participants, to have participants -// removed from the grid. This is because participants have a minimum rendered height. +// removed from the grid, or on subsequent pages. This is because participants +// have a minimum rendered height. +// * Participant videos may have different aspect ratios +// * We want to ensure that presenters and recent speakers are shown on the first page, +// but we also want to minimize tiles jumping around as much as possible. // // There should be more specific comments throughout, but the high-level steps are: // -// 1. Figure out the maximum number of possible rows that could fit on the screen; this is -// `maxRowCount`. -// 2. Split the participants into two groups: ones in the main grid and ones in the -// overflow area. The grid should prioritize participants who have recently spoken. -// 3. For each possible number of rows (starting at 0 and ending at `maxRowCount`), -// distribute participants across the rows at the minimum height. Then find the -// "scalar": how much can we scale these boxes up while still fitting them on the -// screen? The biggest scalar wins as the "best arrangement". -// 4. Lay out this arrangement on the screen. +// 1. Figure out the maximum number of possible rows that could fit on a page; this is +// `maxRowsPerPage`. +// 2. Sort the participants in priority order: we want to fit presenters and recent +// speakers in the grid first +// 3. Figure out which participants should go on each page -- for non-paginated views, +// this is just one page, but for paginated views, we could have many pages. The +// general idea here is to fill up each page row-by-row, with each video as small +// as we allow. +// 4. Try to distribute the videos throughout the grid to find the largest "scalar": +// how much can we scale these boxes up while still fitting them on the screen? +// The biggest scalar wins as the "best arrangement". +// 5. Lay out this arrangement on the screen. + export function GroupCallRemoteParticipants({ + callViewMode, getGroupCallVideoFrameSource, i18n, - isInSpeakerView, + isCallReconnecting, remoteParticipants, setGroupCallVideoRequest, remoteAudioLevels, }: PropsType): JSX.Element { - const [containerDimensions, setContainerDimensions] = useState({ - width: 0, - height: 0, - }); const [gridDimensions, setGridDimensions] = useState({ width: 0, height: 0, }); + const [pageIndex, setPageIndex] = useState(0); + const devicePixelRatio = useDevicePixelRatio(); const getFrameBuffer = useGetCallingFrameBuffer(); @@ -108,195 +129,229 @@ export function GroupCallRemoteParticipants({ const { invisibleDemuxIds, onParticipantVisibilityChanged } = useInvisibleParticipants(remoteParticipants); - // 1. Figure out the maximum number of possible rows that could fit on the screen. - // - // We choose the smaller of these two options: - // - // - The number of participants, which means there'd be one participant per row. - // - The number of possible rows in the container, assuming all participants were - // rendered at minimum height. Doesn't rely on the number of participants—it's some - // simple division. - // - // Could be 0 if (a) there are no participants (b) the container's height is small. - const maxRowCount = Math.min( - remoteParticipants.length, - Math.floor( - containerDimensions.height / (MIN_RENDERED_HEIGHT + PARTICIPANT_MARGIN) - ) + const minRenderedHeight = + callViewMode === CallViewMode.Paginated + ? SMALL_TILES_MIN_HEIGHT + : LARGE_TILES_MIN_HEIGHT; + + const isInSpeakerView = + callViewMode === CallViewMode.Speaker || + callViewMode === CallViewMode.Presentation; + + const isInPaginationView = callViewMode === CallViewMode.Paginated; + const shouldShowOverflow = !isInPaginationView; + + const maxRowWidth = gridDimensions.width; + const maxGridHeight = gridDimensions.height; + + // 1. Figure out the maximum number of possible rows that could fit on the page. + // Could be 0 if (a) there are no participants (b) the container's height is small. + const maxRowsPerPage = Math.floor( + maxGridHeight / (minRenderedHeight + PARTICIPANT_MARGIN) ); - // 2. Split participants into two groups: ones in the main grid and ones in the overflow - // sidebar. - // - // We start by sorting by `presenting` first since presenters should be on the main grid - // then we sort by `speakerTime` so that the most recent speakers are next in - // line for the main grid. Then we split the list in two: one for the grid and one for - // the overflow area. - // - // Once we've sorted participants into their respective groups, we sort them on - // something stable (the `demuxId`, but we could choose something else) so that people - // don't jump around within the group. - // - // These are primarily memoized for clarity, not performance. - const sortedParticipants: Array = useMemo( - () => - remoteParticipants - .concat() - .sort( - (a, b) => - Number(b.presenting || 0) - Number(a.presenting || 0) || - (b.speakerTime || -Infinity) - (a.speakerTime || -Infinity) - ), - [remoteParticipants] - ); - const gridParticipants: Array = - useMemo(() => { - if (!sortedParticipants.length) { - return []; - } + // 2. Sort the participants in priority order: by `presenting` first, since presenters + // should be on the main grid, then by `speakerTime` so that the most recent speakers + // are next in line for the first pages of the grid + const prioritySortedParticipants: Array = + useMemo( + () => + remoteParticipants + .concat() + .sort( + (a, b) => + Number(b.presenting || 0) - Number(a.presenting || 0) || + (b.speakerTime || -Infinity) - (a.speakerTime || -Infinity) + ), + [remoteParticipants] + ); - const candidateParticipants = isInSpeakerView - ? [sortedParticipants[0]] - : sortedParticipants; - - // Imagine that we laid out all of the rows end-to-end. That's the maximum total - // width. So if there were 5 rows and the container was 100px wide, then we can't - // possibly fit more than 500px of participants. - const maxTotalWidth = maxRowCount * containerDimensions.width; - - // We do the same thing for participants, "laying them out end-to-end" until they - // exceed the maximum total width. - let totalWidth = 0; - return takeWhile(candidateParticipants, remoteParticipant => { - totalWidth += remoteParticipant.videoAspectRatio * MIN_RENDERED_HEIGHT; - return totalWidth < maxTotalWidth; - }).sort(stableParticipantComparator); - }, [ - containerDimensions.width, - isInSpeakerView, - maxRowCount, - sortedParticipants, - ]); - const overflowedParticipants: Array = useMemo( - () => - sortedParticipants - .slice(gridParticipants.length) - .sort(stableParticipantComparator), - [sortedParticipants, gridParticipants.length] - ); - - // 3. For each possible number of rows (starting at 0 and ending at `maxRowCount`), - // distribute participants across the rows at the minimum height. Then find the - // "scalar": how much can we scale these boxes up while still fitting them on the - // screen? The biggest scalar wins as the "best arrangement". - const gridArrangement: GridArrangement = useMemo(() => { - let bestArrangement: GridArrangement = { - scalar: -1, - rows: [], - }; - - if (!gridParticipants.length) { - return bestArrangement; + // 3. Layout the participants on each page. The general algorithm is: first, try to fill + // up each page with as many participants as possible at the smallest acceptable video + // height. Second, sort the participants that fit on each page by a stable sort order, + // and make sure they still fit on the page! Third, add tiles at the beginning and end + // of each page (if paginated) to act as back and next buttons. + const gridParticipantsByPage: Array = useMemo(() => { + if (!prioritySortedParticipants.length) { + return []; } - for (let rowCount = 1; rowCount <= maxRowCount; rowCount += 1) { - // We do something pretty naïve here and chunk the grid's participants into rows. - // For example, if there were 12 grid participants and `rowCount === 3`, there - // would be 4 participants per row. - // - // This naïve chunking is suboptimal in terms of absolute best fit, but it is much - // faster and simpler than trying to do this perfectly. In practice, this works - // fine in the UI from our testing. - const numberOfParticipantsInRow = Math.ceil( - gridParticipants.length / rowCount - ); - const rows = chunk(gridParticipants, numberOfParticipantsInRow); - - // We need to find the scalar for this arrangement. Imagine that we have these - // participants at the minimum heights, and we want to scale everything up until - // it's about to overflow. - // - // We don't want it to overflow horizontally or vertically, so we calculate a - // "width scalar" and "height scalar" and choose the smaller of the two. (Choosing - // the LARGER of the two could cause overflow.) - const widestRow = maxBy(rows, totalRemoteParticipantWidthAtMinHeight); - if (!widestRow) { - log.error('Unable to find the widest row, which should be impossible'); - continue; - } - const widthScalar = - (gridDimensions.width - (widestRow.length + 1) * PARTICIPANT_MARGIN) / - totalRemoteParticipantWidthAtMinHeight(widestRow); - const heightScalar = - (gridDimensions.height - (rowCount + 1) * PARTICIPANT_MARGIN) / - (rowCount * MIN_RENDERED_HEIGHT); - const scalar = Math.min(widthScalar, heightScalar); - - // If this scalar is the best one so far, we use that. - if (scalar > bestArrangement.scalar) { - bestArrangement = { scalar, rows }; - } + if (!maxRowsPerPage) { + return []; } - return bestArrangement; + if (isInSpeakerView) { + return [ + { + rows: [[prioritySortedParticipants[0]]], + hasSpaceRemaining: false, + numParticipants: 1, + }, + ]; + } + + return getGridParticipantsByPage({ + participants: prioritySortedParticipants, + maxRowWidth, + maxPages: isInPaginationView ? Infinity : 1, + maxRowsPerPage, + minRenderedHeight, + maxParticipantsPerPage: MAX_PARTICIPANTS_PER_PAGE, + currentPage: pageIndex, + }); }, [ - gridParticipants, - maxRowCount, - gridDimensions.width, - gridDimensions.height, + maxRowWidth, + isInPaginationView, + isInSpeakerView, + maxRowsPerPage, + minRenderedHeight, + pageIndex, + prioritySortedParticipants, ]); - // 4. Lay out this arrangement on the screen. - const gridParticipantHeight = Math.floor( - gridArrangement.scalar * MIN_RENDERED_HEIGHT + // Make sure we're not on a page that no longer exists (e.g. if people left the call) + if ( + pageIndex >= gridParticipantsByPage.length && + gridParticipantsByPage.length > 0 + ) { + setPageIndex(gridParticipantsByPage.length - 1); + } + + const totalParticipantsInGrid = gridParticipantsByPage.reduce( + (pageCount, { numParticipants }) => pageCount + numParticipants, + 0 + ); + + // In speaker or overflow views, not all participants will be on the grid; they'll + // get put in the overflow zone. + const overflowedParticipants: Array = useMemo( + () => + isInPaginationView + ? [] + : prioritySortedParticipants + .slice(totalParticipantsInGrid) + .sort(stableParticipantComparator), + [isInPaginationView, prioritySortedParticipants, totalParticipantsInGrid] + ); + + const participantsOnOtherPages = useMemo( + () => + gridParticipantsByPage + .map((page, index) => { + if (index === pageIndex) { + return []; + } + return page.rows.flat(); + }) + .flat() + .filter(isGroupCallRemoteParticipant), + [gridParticipantsByPage, pageIndex] + ); + + const currentPage = gridParticipantsByPage.at(pageIndex) ?? { + rows: [], + }; + + // 4. Try to arrange the current page such that we can scale the videos up + // as much as possible. + const gridArrangement = arrangeParticipantsInGrid({ + participantsInRows: currentPage.rows, + maxRowsPerPage, + maxRowWidth, + maxGridHeight, + minRenderedHeight, + }); + + const nextPage = () => { + setPageIndex(index => index + 1); + }; + + const prevPage = () => { + setPageIndex(index => Math.max(0, index - 1)); + }; + + // 5. Lay out the current page on the screen. + const gridParticipantHeight = Math.round( + gridArrangement.scalar * minRenderedHeight ); const gridParticipantHeightWithMargin = gridParticipantHeight + PARTICIPANT_MARGIN; const gridTotalRowHeightWithMargin = - gridParticipantHeightWithMargin * gridArrangement.rows.length; - const gridTopOffset = Math.floor( - (gridDimensions.height - gridTotalRowHeightWithMargin) / 2 + gridParticipantHeightWithMargin * gridArrangement.rows.length - + PARTICIPANT_MARGIN; + const gridTopOffset = Math.max( + 0, + Math.round((gridDimensions.height - gridTotalRowHeightWithMargin) / 2) ); const rowElements: Array> = gridArrangement.rows.map( - (remoteParticipantsInRow, index) => { + (tiles, index) => { const top = gridTopOffset + index * gridParticipantHeightWithMargin; const totalRowWidthWithoutMargins = - totalRemoteParticipantWidthAtMinHeight(remoteParticipantsInRow) * + totalRowWidthAtHeight(tiles, minRenderedHeight) * gridArrangement.scalar; const totalRowWidth = - totalRowWidthWithoutMargins + - PARTICIPANT_MARGIN * (remoteParticipantsInRow.length - 1); - const leftOffset = Math.floor((gridDimensions.width - totalRowWidth) / 2); + totalRowWidthWithoutMargins + PARTICIPANT_MARGIN * (tiles.length - 1); + const leftOffset = Math.max( + 0, + Math.round((gridDimensions.width - totalRowWidth) / 2) + ); let rowWidthSoFar = 0; - return remoteParticipantsInRow.map(remoteParticipant => { - const { demuxId, videoAspectRatio } = remoteParticipant; - - const audioLevel = remoteAudioLevels.get(demuxId) ?? 0; - - const renderedWidth = Math.floor( - videoAspectRatio * gridParticipantHeight - ); + return tiles.map(tile => { const left = rowWidthSoFar + leftOffset; + const renderedWidth = Math.round( + tile.videoAspectRatio * gridParticipantHeight + ); + rowWidthSoFar += renderedWidth + PARTICIPANT_MARGIN; + if (isPaginationButton(tile)) { + const isNextButton = tile.paginationButtonType === 'next'; + const isPrevButton = tile.paginationButtonType === 'prev'; + return ( + + ); + } + return ( ); }); @@ -314,30 +369,37 @@ export function GroupCallRemoteParticipants({ switch (videoRequestMode) { case VideoRequestMode.Normal: videoRequest = [ - ...gridParticipants.map(participant => { - let scalar: number; - if (participant.sharingScreen) { - // We want best-resolution video if someone is sharing their screen. - scalar = Math.max(devicePixelRatio, 1); - } else { - scalar = VIDEO_REQUEST_SCALAR; - } - return { - demuxId: participant.demuxId, - width: clamp( - Math.floor( - gridParticipantHeight * participant.videoAspectRatio * scalar + ...currentPage.rows + .flat() + // Filter out any next/previous page buttons + .filter(isGroupCallRemoteParticipant) + .map(participant => { + let scalar: number; + if (participant.sharingScreen) { + // We want best-resolution video if someone is sharing their screen. + scalar = Math.max(devicePixelRatio, 1); + } else { + scalar = VIDEO_REQUEST_SCALAR; + } + return { + demuxId: participant.demuxId, + width: clamp( + Math.round( + gridParticipantHeight * + participant.videoAspectRatio * + scalar + ), + 1, + MAX_FRAME_WIDTH ), - 1, - MAX_FRAME_WIDTH - ), - height: clamp( - Math.floor(gridParticipantHeight * scalar), - 1, - MAX_FRAME_HEIGHT - ), - }; - }), + height: clamp( + Math.round(gridParticipantHeight * scalar), + 1, + MAX_FRAME_HEIGHT + ), + }; + }), + ...participantsOnOtherPages.map(nonRenderedRemoteParticipant), ...overflowedParticipants.map(participant => { if (invisibleDemuxIds.has(participant.demuxId)) { return nonRenderedRemoteParticipant(participant); @@ -346,12 +408,12 @@ export function GroupCallRemoteParticipants({ return { demuxId: participant.demuxId, width: clamp( - Math.floor(OVERFLOW_PARTICIPANT_WIDTH * VIDEO_REQUEST_SCALAR), + Math.round(OVERFLOW_PARTICIPANT_WIDTH * VIDEO_REQUEST_SCALAR), 1, MAX_FRAME_WIDTH ), height: clamp( - Math.floor( + Math.round( (OVERFLOW_PARTICIPANT_WIDTH / participant.videoAspectRatio) * VIDEO_REQUEST_SCALAR ), @@ -381,57 +443,79 @@ export function GroupCallRemoteParticipants({ videoRequest = remoteParticipants.map(nonRenderedRemoteParticipant); break; } - setGroupCallVideoRequest( videoRequest, clamp(gridParticipantHeight, 0, MAX_FRAME_HEIGHT) ); }, [ devicePixelRatio, + currentPage.rows, gridParticipantHeight, - gridParticipants, invisibleDemuxIds, overflowedParticipants, remoteParticipants, setGroupCallVideoRequest, videoRequestMode, + participantsOnOtherPages, ]); return ( - { - setContainerDimensions(size); - }} - > - {containerRef => ( -
- { - setGridDimensions(size); - }} - > - {gridRef => ( -
- {flatten(rowElements)} -
- )} -
+
+
+ { + setGridDimensions(size); + }} + > + {gridRef => ( +
+ {flatten(rowElements)} - -
- )} -
+ {isInPaginationView && ( + <> + {pageIndex > 0 ? ( + + ) : null} + {pageIndex < gridParticipantsByPage.length - 1 ? ( + + ) : null} + + )} +
+ )} + +
+ + {shouldShowOverflow && overflowedParticipants.length > 0 ? ( + + ) : null} +
); } @@ -516,19 +600,425 @@ function useVideoRequestMode(): VideoRequestMode { return result; } -function totalRemoteParticipantWidthAtMinHeight( - remoteParticipants: ReadonlyArray +function totalRowWidthAtHeight( + participantsInRow: ReadonlyArray< + Pick + >, + height: number ): number { - return remoteParticipants.reduce( - (result, { videoAspectRatio }) => - result + videoAspectRatio * MIN_RENDERED_HEIGHT, + return participantsInRow.reduce( + (result, participant) => + result + participantWidthAtHeight(participant, height), 0 ); } +function participantWidthAtHeight( + participant: Pick, + height: number +) { + return participant.videoAspectRatio * height; +} + function stableParticipantComparator( a: Readonly<{ demuxId: number }>, b: Readonly<{ demuxId: number }> ): number { return a.demuxId - b.demuxId; } + +type ParticipantsInPageType< + T extends { videoAspectRatio: number } = ParticipantTileType +> = { + rows: Array>; + numParticipants: number; +}; + +type PageLayoutPropsType = { + maxRowWidth: number; + minRenderedHeight: number; + maxRowsPerPage: number; + maxParticipantsPerPage: number; +}; +function getGridParticipantsByPage({ + participants, + maxPages, + currentPage, + ...pageLayoutProps +}: PageLayoutPropsType & { + participants: Array; + maxPages: number; + currentPage?: number; +}): Array { + if (!participants.length) { + return []; + } + + const pages: Array = []; + + function getTotalParticipantsOnGrid() { + return pages.reduce((count, page) => count + page.numParticipants, 0); + } + + let remainingParticipants = [...participants]; + while (remainingParticipants.length) { + if (currentPage === pages.length - 1) { + // Optimization: we can stop early, we don't have to lay out the remainder of the + // pages + pages.push({ + rows: [remainingParticipants], + numParticipants: remainingParticipants.length, + }); + return pages; + } + + const nextPageInPriorityOrder = getNextPage({ + participants: remainingParticipants, + leaveRoomForPrevPageButton: pages.length > 0, + leaveRoomForNextPageButton: pages.length + 1 < maxPages, + ...pageLayoutProps, + }); + + // We got the next page, but it's in priority order; let's see if these participants + // also fit in sorted order + const priorityParticipantsOnNextPage = nextPageInPriorityOrder.rows.flat(); + let sortedParticipantsHopingToFitOnPage = [ + ...priorityParticipantsOnNextPage, + ].sort(stableParticipantComparator); + let nextPageInSortedOrder = getNextPage({ + participants: sortedParticipantsHopingToFitOnPage, + leaveRoomForPrevPageButton: pages.length > 0, + leaveRoomForNextPageButton: pages.length + 1 < maxPages, + isSubsetOfAllParticipants: + sortedParticipantsHopingToFitOnPage.length < + remainingParticipants.length, + ...pageLayoutProps, + }); + + let nextPage: ParticipantsInPageType | undefined; + + if ( + nextPageInSortedOrder.numParticipants === + nextPageInPriorityOrder.numParticipants + ) { + // Great, we're able to show everyone. It's possible that there is now extra space + // and we could show more people, but let's leave it here for simplicity + nextPage = nextPageInSortedOrder; + } else { + // We weren't able to fit everyone. Let's remove the least-prioritized person and + // try again. It's pretty unlikely this will take more than 1 attempt, but + // let's take more and more participants off the screen if it takes a lot of + // attempts so we don't have to iterate dozens of times. + const PARTICIPANTS_TO_REMOVE_PER_ATTEMPT = [1, 1, 1, 2, 5]; + const MAX_ATTEMPTS = 5; + let attemptNumber = 0; + + while ( + sortedParticipantsHopingToFitOnPage.length && + attemptNumber < MAX_ATTEMPTS + ) { + const numLeastPrioritizedParticipantsToRemove = + PARTICIPANTS_TO_REMOVE_PER_ATTEMPT[ + Math.min( + attemptNumber, + PARTICIPANTS_TO_REMOVE_PER_ATTEMPT.length - 1 + ) + ]; + + const leastPrioritizedParticipantIds = new Set( + priorityParticipantsOnNextPage + .splice( + -1 * numLeastPrioritizedParticipantsToRemove, + numLeastPrioritizedParticipantsToRemove + ) + .map(participant => participant.demuxId) + ); + + sortedParticipantsHopingToFitOnPage = + sortedParticipantsHopingToFitOnPage.filter( + participant => + !leastPrioritizedParticipantIds.has(participant.demuxId) + ); + + nextPageInSortedOrder = getNextPage({ + participants: sortedParticipantsHopingToFitOnPage, + leaveRoomForPrevPageButton: pages.length > 0, + leaveRoomForNextPageButton: pages.length + 1 < maxPages, + ...pageLayoutProps, + }); + + // Are we able to fill all of them now? Great, let's ship it. + if ( + nextPageInSortedOrder.numParticipants === + sortedParticipantsHopingToFitOnPage.length + ) { + nextPage = nextPageInSortedOrder; + break; + } + attemptNumber += 1; + } + + if (!nextPage) { + log.warn( + `GroupCallRemoteParticipants: failed after ${attemptNumber} attempts to layout + the page; pageIndex: ${pages.length}, \ + # fit in priority order: ${nextPageInPriorityOrder.numParticipants}, \ + # fit in sorted order: ${nextPageInSortedOrder.numParticipants}` + ); + nextPage = nextPageInSortedOrder; + } + } + + if (!nextPage) { + break; + } + + const nextPageTiles = + nextPage as ParticipantsInPageType; + + // Add a previous page tile if needed + if (pages.length > 0) { + nextPageTiles.rows[0].unshift({ + isPaginationButton: true, + paginationButtonType: 'prev', + videoAspectRatio: PAGINATION_BUTTON_ASPECT_RATIO, + numParticipants: getTotalParticipantsOnGrid(), + }); + } + + if (!nextPage.numParticipants) { + break; + } + + remainingParticipants = remainingParticipants.slice( + nextPage.numParticipants + ); + + pages.push(nextPage); + + if (pages.length === maxPages) { + break; + } + + // Add a next page tile if needed + if (remainingParticipants.length) { + nextPageTiles.rows.at(-1)?.push({ + isPaginationButton: true, + paginationButtonType: 'next', + videoAspectRatio: PAGINATION_BUTTON_ASPECT_RATIO, + numParticipants: remainingParticipants.length, + }); + } + } + return pages; +} + +/** + * Attempt to fill a new page with as many participants as will fit, leaving room for + * next/prev page buttons as needed. Participants will be added in the order provided. + * + * @returns ParticipantsInPageType, representing the participants that fit on this page + * assuming they are rendered at minimum height. Does not include prev/next buttons, + * but will leave space for them if needed. Participants are not necessarily + * returned in the row-distribution that will maximize video scaling; that should + * be done subsequently. + */ +function getNextPage({ + participants, + maxRowWidth, + minRenderedHeight, + maxRowsPerPage, + maxParticipantsPerPage, + leaveRoomForPrevPageButton, + leaveRoomForNextPageButton, + isSubsetOfAllParticipants, +}: PageLayoutPropsType & { + participants: Array; + leaveRoomForPrevPageButton: boolean; + leaveRoomForNextPageButton: boolean; + isSubsetOfAllParticipants?: boolean; +}): ParticipantsInPageType { + const paginationButtonWidth = participantWidthAtHeight( + { + videoAspectRatio: PAGINATION_BUTTON_ASPECT_RATIO, + }, + minRenderedHeight + ); + let rowWidth = leaveRoomForPrevPageButton + ? paginationButtonWidth + PARTICIPANT_MARGIN + : 0; + + // Initialize fresh page with empty first row + const rows: Array> = [[]]; + let row = rows[0]; + let numParticipants = 0; + + // Start looping through participants and adding them to the rows one-by-one + for (let i = 0; i < participants.length; i += 1) { + const participant = participants[i]; + const isLastParticipant = + !isSubsetOfAllParticipants && i === participants.length - 1; + + const participantWidth = participantWidthAtHeight( + participant, + minRenderedHeight + ); + const isLastRow = rows.length === maxRowsPerPage; + const shouldShowNextButtonInThisRow = + isLastRow && !isLastParticipant && leaveRoomForNextPageButton; + + const currentRowMaxWidth = shouldShowNextButtonInThisRow + ? maxRowWidth - (paginationButtonWidth + PARTICIPANT_MARGIN) + : maxRowWidth; + + const participantFitsOnRow = + rowWidth + participantWidth + (row.length ? PARTICIPANT_MARGIN : 0) <= + currentRowMaxWidth; + + if (participantFitsOnRow) { + rowWidth += participantWidth + (row.length ? PARTICIPANT_MARGIN : 0); + row.push(participant); + numParticipants += 1; + + if (numParticipants === maxParticipantsPerPage) { + return { rows, numParticipants }; + } + } else { + if (isLastRow) { + return { rows, numParticipants }; + } + + // Start a new row! + row = [participant]; + rows.push(row); + numParticipants += 1; + rowWidth = participantWidth; + } + } + return { + rows, + numParticipants, + }; +} + +/** + * Given an arrangement of participants in rows that we know fits on a page at minimum + * rendered height, try to find an arrangement that maximizes video size, or return the + * provided arrangement with maximal video size. The result of this is ready to be + * laid out on the screen. + * + * @returns GridArrangement: { + * rows: participants in rows, + * scalar: the scalar by which can scale every video on the page and still fit + * } + */ +function arrangeParticipantsInGrid({ + participantsInRows, + maxRowWidth, + minRenderedHeight, + maxRowsPerPage, + maxGridHeight, +}: { + participantsInRows: Array>; + maxRowWidth: number; + minRenderedHeight: number; + maxRowsPerPage: number; + maxGridHeight: number; +}): GridArrangement { + // Start out with the arrangement that was prepared by getGridParticipantsByPage. + // We know this arrangement (added one-by-one) fits, so its scalar is + // guaranteed to be >= 1. Our chunking strategy below might not arrive at such + // an arrangement. + let bestArrangement: GridArrangement = { + scalar: getMaximumScaleForRows({ + maxRowWidth, + minRenderedHeight, + rows: participantsInRows, + maxGridHeight, + }), + rows: participantsInRows, + }; + + const participants = participantsInRows.flat(); + + // For each possible number of rows (starting at 0 and ending at `maxRowCount`), + // distribute participants across the rows at the minimum height. Then find the + // "scalar": how much can we scale these boxes up while still fitting them on the + // screen? The biggest scalar wins as the "best arrangement". + for (let rowCount = 1; rowCount <= maxRowsPerPage; rowCount += 1) { + // We do something pretty naĂŻve here and chunk the grid's participants into rows. + // For example, if there were 12 grid participants and `rowCount === 3`, there + // would be 4 participants per row. + // + // This naĂŻve chunking is suboptimal in terms of absolute best fit, but it is much + // faster and simpler than trying to do this perfectly. In practice, this works + // fine in the UI from our testing. + const numberOfParticipantsInRow = Math.ceil(participants.length / rowCount); + const rows = chunk(participants, numberOfParticipantsInRow); + + const scalar = getMaximumScaleForRows({ + maxRowWidth, + minRenderedHeight, + rows, + maxGridHeight, + }); + + if (scalar > bestArrangement.scalar) { + bestArrangement = { + scalar, + rows, + }; + } + } + + return bestArrangement; +} + +// We need to find the scalar for this arrangement. Imagine that we have these +// participants at the minimum heights, and we want to scale everything up until +// it's about to overflow. +function getMaximumScaleForRows({ + maxRowWidth, + minRenderedHeight, + maxGridHeight, + rows, +}: { + maxRowWidth: number; + minRenderedHeight: number; + maxGridHeight: number; + rows: Array>; +}): number { + if (!rows.length) { + return 0; + } + const widestRow = maxBy(rows, x => + totalRowWidthAtHeight(x, minRenderedHeight) + ); + + strictAssert(widestRow, 'Could not find widestRow'); + + // We don't want it to overflow horizontally or vertically, so we calculate a + // "width scalar" and "height scalar" and choose the smaller of the two. (Choosing + // the LARGER of the two could cause overflow.) + const widthScalar = + (maxRowWidth - (widestRow.length - 1) * PARTICIPANT_MARGIN) / + totalRowWidthAtHeight(widestRow, minRenderedHeight); + + const heightScalar = + (maxGridHeight - (rows.length - 1) * PARTICIPANT_MARGIN) / + (rows.length * minRenderedHeight); + + return Math.min(widthScalar, heightScalar); +} + +function isGroupCallRemoteParticipant( + tile: ParticipantTileType +): tile is GroupCallRemoteParticipantType { + return 'demuxId' in tile; +} + +function isPaginationButton( + tile: ParticipantTileType +): tile is PaginationButtonType { + return 'isPaginationButton' in tile; +} diff --git a/ts/components/GroupDescriptionInput.stories.tsx b/ts/components/GroupDescriptionInput.stories.tsx index 390fcdd6ee..b692f4fbdd 100644 --- a/ts/components/GroupDescriptionInput.stories.tsx +++ b/ts/components/GroupDescriptionInput.stories.tsx @@ -2,17 +2,17 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState } from 'react'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; - +import type { PropsType } from './GroupDescriptionInput'; import { GroupDescriptionInput } from './GroupDescriptionInput'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/GroupDescriptionInput', -}; +} satisfies Meta; function Wrapper({ disabled, diff --git a/ts/components/GroupDescriptionInput.tsx b/ts/components/GroupDescriptionInput.tsx index 0534a8d101..2a470d819c 100644 --- a/ts/components/GroupDescriptionInput.tsx +++ b/ts/components/GroupDescriptionInput.tsx @@ -6,7 +6,7 @@ import React, { forwardRef } from 'react'; import { Input } from './Input'; import type { LocalizerType } from '../types/Util'; -type PropsType = { +export type PropsType = { disabled?: boolean; i18n: LocalizerType; onChangeValue: (value: string) => void; diff --git a/ts/components/GroupTitleInput.stories.tsx b/ts/components/GroupTitleInput.stories.tsx index af128f3506..d873de91de 100644 --- a/ts/components/GroupTitleInput.stories.tsx +++ b/ts/components/GroupTitleInput.stories.tsx @@ -2,17 +2,17 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState } from 'react'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; - +import type { PropsType } from './GroupTitleInput'; import { GroupTitleInput } from './GroupTitleInput'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/GroupTitleInput', -}; +} satisfies Meta; function Wrapper({ disabled, diff --git a/ts/components/GroupTitleInput.tsx b/ts/components/GroupTitleInput.tsx index 23def66a20..ebd75e6c68 100644 --- a/ts/components/GroupTitleInput.tsx +++ b/ts/components/GroupTitleInput.tsx @@ -6,7 +6,7 @@ import React, { forwardRef } from 'react'; import { Input } from './Input'; import type { LocalizerType } from '../types/Util'; -type PropsType = { +export type PropsType = { disabled?: boolean; i18n: LocalizerType; onChangeValue: (value: string) => void; diff --git a/ts/components/GroupV1MigrationDialog.stories.tsx b/ts/components/GroupV1MigrationDialog.stories.tsx index e86725e4e1..a6464eb5d9 100644 --- a/ts/components/GroupV1MigrationDialog.stories.tsx +++ b/ts/components/GroupV1MigrationDialog.stories.tsx @@ -5,6 +5,7 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './GroupV1MigrationDialog'; import { GroupV1MigrationDialog } from './GroupV1MigrationDialog'; import type { ConversationType } from '../state/ducks/conversations'; @@ -48,16 +49,12 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/GroupV1MigrationDialog', -}; +} satisfies Meta; export function NotYetMigratedBasic(): JSX.Element { return ; } -NotYetMigratedBasic.story = { - name: 'Not yet migrated, basic', -}; - export function MigratedBasic(): JSX.Element { return ( ); } - -NotYetMigratedJustDroppedMember.story = { - name: 'Not yet migrated, just dropped member', -}; diff --git a/ts/components/GroupV2JoinDialog.stories.tsx b/ts/components/GroupV2JoinDialog.stories.tsx index ab05156166..6a348fad4f 100644 --- a/ts/components/GroupV2JoinDialog.stories.tsx +++ b/ts/components/GroupV2JoinDialog.stories.tsx @@ -2,9 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { boolean, number, text } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './GroupV2JoinDialog'; import { GroupV2JoinDialog } from './GroupV2JoinDialog'; import { setupI18n } from '../util/setupI18n'; @@ -13,13 +12,10 @@ import enMessages from '../../_locales/en/messages.json'; const i18n = setupI18n('en', enMessages); const createProps = (overrideProps: Partial = {}): PropsType => ({ - memberCount: number('memberCount', overrideProps.memberCount || 12), + memberCount: overrideProps.memberCount ?? 12, avatar: overrideProps.avatar, - title: text('title', overrideProps.title || 'Random Group!'), - approvalRequired: boolean( - 'approvalRequired', - overrideProps.approvalRequired || false - ), + title: overrideProps.title ?? 'Random Group!', + approvalRequired: overrideProps.approvalRequired ?? false, groupDescription: overrideProps.groupDescription, join: action('join'), onClose: action('onClose'), @@ -28,7 +24,9 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/GroupV2JoinDialog', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function Basic(): JSX.Element { return ; @@ -45,10 +43,6 @@ export function ApprovalRequired(): JSX.Element { ); } -ApprovalRequired.story = { - name: 'Approval required', -}; - export function WithAvatar(): JSX.Element { return ( = []; diff --git a/ts/components/InContactsIcon.stories.tsx b/ts/components/InContactsIcon.stories.tsx index 5c5acb6323..42db8da1b2 100644 --- a/ts/components/InContactsIcon.stories.tsx +++ b/ts/components/InContactsIcon.stories.tsx @@ -2,16 +2,17 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; +import type { PropsType } from './InContactsIcon'; import { InContactsIcon } from './InContactsIcon'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/InContactsIcon', -}; +} satisfies Meta; export function Default(): JSX.Element { return ; diff --git a/ts/components/InContactsIcon.tsx b/ts/components/InContactsIcon.tsx index 9ee209a45c..e0cfe0d218 100644 --- a/ts/components/InContactsIcon.tsx +++ b/ts/components/InContactsIcon.tsx @@ -7,7 +7,7 @@ import classNames from 'classnames'; import { Tooltip } from './Tooltip'; import type { LocalizerType } from '../types/Util'; -type PropsType = { +export type PropsType = { className?: string; tooltipContainerRef?: React.RefObject; i18n: LocalizerType; diff --git a/ts/components/Inbox.stories.tsx b/ts/components/Inbox.stories.tsx index 29f6306556..b2f93e4dfc 100644 --- a/ts/components/Inbox.stories.tsx +++ b/ts/components/Inbox.stories.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState, useEffect, useMemo } from 'react'; -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import { noop } from 'lodash'; import { Inbox } from './Inbox'; @@ -16,41 +16,15 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Inbox', - argTypes: { - i18n: { - defaultValue: i18n, - }, - hasInitialLoadCompleted: { - defaultValue: false, - }, - daysAgo: { - control: 'select', - defaultValue: undefined, - options: [undefined, 1, 2, 3, 7, 14, 21], - }, - isCustomizingPreferredReactions: { - defaultValue: false, - }, - onConversationClosed: { - action: true, - }, - onConversationOpened: { - action: true, - }, - scrollToMessage: { - action: true, - }, - showConversation: { - action: true, - }, - showWhatsNewModal: { - action: true, - }, + args: { + i18n, + hasInitialLoadCompleted: false, + isCustomizingPreferredReactions: false, }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = ({ +const Template: StoryFn = ({ daysAgo, ...args }) => { @@ -84,15 +58,9 @@ const Template: Story = ({ {...args} firstEnvelopeTimestamp={firstEnvelopeTimestamp} envelopeTimestamp={envelopeTimestamp} - renderConversationView={() =>
} renderCustomizingPreferredReactionsModal={() =>
} - renderLeftPane={() =>
} - renderMiniPlayer={() =>
} /> ); }; export const Default = Template.bind({}); -Default.story = { - name: 'Default', -}; diff --git a/ts/components/Inbox.tsx b/ts/components/Inbox.tsx index 558be808a2..74a6233521 100644 --- a/ts/components/Inbox.tsx +++ b/ts/components/Inbox.tsx @@ -3,19 +3,10 @@ import type { ReactNode } from 'react'; import React, { useEffect, useState, useMemo } from 'react'; - -import type { ShowConversationType } from '../state/ducks/conversations'; import type { LocalizerType } from '../types/Util'; - import * as log from '../logging/log'; import { SECOND, DAY } from '../util/durations'; -import { ToastStickerPackInstallFailed } from './ToastStickerPackInstallFailed'; -import { WhatsNewLink } from './WhatsNewLink'; -import { showToast } from '../util/showToast'; -import { strictAssert } from '../util/assert'; -import { TargetedMessageSource } from '../state/ducks/conversationsEnums'; -import { usePrevious } from '../hooks/usePrevious'; -import { Environment, getEnvironment } from '../environment'; +import type { SmartNavTabsProps } from '../state/smart/NavTabs'; export type PropsType = { firstEnvelopeTimestamp: number | undefined; @@ -23,18 +14,13 @@ export type PropsType = { hasInitialLoadCompleted: boolean; i18n: LocalizerType; isCustomizingPreferredReactions: boolean; - onConversationClosed: (id: string, reason: string) => unknown; - onConversationOpened: (id: string, messageId?: string) => unknown; - renderConversationView: () => JSX.Element; + navTabsCollapsed: boolean; + onToggleNavTabsCollapse: (navTabsCollapsed: boolean) => unknown; + renderCallsTab: () => JSX.Element; + renderChatsTab: () => JSX.Element; renderCustomizingPreferredReactionsModal: () => JSX.Element; - renderLeftPane: () => JSX.Element; - renderMiniPlayer: (options: { shouldFlow: boolean }) => JSX.Element; - scrollToMessage: (conversationId: string, messageId: string) => unknown; - selectedConversationId?: string; - targetedMessage?: string; - targetedMessageSource?: TargetedMessageSource; - showConversation: ShowConversationType; - showWhatsNewModal: () => unknown; + renderNavTabs: (props: SmartNavTabsProps) => JSX.Element; + renderStoriesTab: () => JSX.Element; }; export function Inbox({ @@ -43,27 +29,17 @@ export function Inbox({ hasInitialLoadCompleted, i18n, isCustomizingPreferredReactions, - onConversationClosed, - onConversationOpened, - renderConversationView, + navTabsCollapsed, + onToggleNavTabsCollapse, + renderCallsTab, + renderChatsTab, renderCustomizingPreferredReactionsModal, - renderLeftPane, - renderMiniPlayer, - scrollToMessage, - selectedConversationId, - targetedMessage, - targetedMessageSource, - showConversation, - showWhatsNewModal, + renderNavTabs, + renderStoriesTab, }: PropsType): JSX.Element { const [internalHasInitialLoadCompleted, setInternalHasInitialLoadCompleted] = useState(hasInitialLoadCompleted); - const prevConversationId = usePrevious( - selectedConversationId, - selectedConversationId - ); - const now = useMemo(() => Date.now(), []); const midnight = useMemo(() => { const date = new Date(now); @@ -74,80 +50,6 @@ export function Inbox({ return date.getTime(); }, [now]); - useEffect(() => { - if (prevConversationId !== selectedConversationId) { - if (prevConversationId) { - onConversationClosed(prevConversationId, 'opened another conversation'); - } - - if (selectedConversationId) { - onConversationOpened(selectedConversationId, targetedMessage); - } - } else if ( - selectedConversationId && - targetedMessage && - targetedMessageSource !== TargetedMessageSource.Focus - ) { - scrollToMessage(selectedConversationId, targetedMessage); - } - - if (!selectedConversationId) { - return; - } - - const conversation = window.ConversationController.get( - selectedConversationId - ); - strictAssert(conversation, 'Conversation must be found'); - - conversation.setMarkedUnread(false); - }, [ - onConversationClosed, - onConversationOpened, - prevConversationId, - scrollToMessage, - selectedConversationId, - targetedMessage, - targetedMessageSource, - ]); - - useEffect(() => { - function refreshConversation({ - newId, - oldId, - }: { - newId: string; - oldId: string; - }) { - if (prevConversationId === oldId) { - showConversation({ conversationId: newId }); - } - } - - // Close current opened conversation to reload the group information once - // linked. - function unload() { - if (!prevConversationId) { - return; - } - onConversationClosed(prevConversationId, 'force unload requested'); - } - - function packInstallFailed() { - showToast(ToastStickerPackInstallFailed); - } - - window.Whisper.events.on('pack-install-failed', packInstallFailed); - window.Whisper.events.on('refreshConversation', refreshConversation); - window.Whisper.events.on('setupAsNewDevice', unload); - - return () => { - window.Whisper.events.off('pack-install-failed', packInstallFailed); - window.Whisper.events.off('refreshConversation', refreshConversation); - window.Whisper.events.off('setupAsNewDevice', unload); - }; - }, [onConversationClosed, prevConversationId, showConversation]); - useEffect(() => { if (internalHasInitialLoadCompleted) { return; @@ -186,12 +88,6 @@ export function Inbox({ setInternalHasInitialLoadCompleted(hasInitialLoadCompleted); }, [hasInitialLoadCompleted]); - useEffect(() => { - if (!selectedConversationId) { - window.SignalCI?.handleEvent('empty-inbox:rendered', null); - } - }, [selectedConversationId]); - if (!internalHasInitialLoadCompleted) { let loadingProgress = 0; if ( @@ -264,37 +160,13 @@ export function Inbox({ <>
- -
{renderLeftPane()}
- -
-
- {selectedConversationId && ( -
- {renderConversationView()} -
- )} - {!prevConversationId && ( -
- {renderMiniPlayer({ shouldFlow: false })} -
-

- {getEnvironment() !== Environment.Staging - ? i18n('icu:welcomeToSignal') - : 'THIS IS A STAGING DESKTOP'} -

-

- -

-
- )} -
+ {renderNavTabs({ + navTabsCollapsed, + onToggleNavTabsCollapse, + renderChatsTab, + renderCallsTab, + renderStoriesTab, + })}
{activeModal} diff --git a/ts/components/IncomingCallBar.stories.tsx b/ts/components/IncomingCallBar.stories.tsx index 0228afebca..099e55c19c 100644 --- a/ts/components/IncomingCallBar.stories.tsx +++ b/ts/components/IncomingCallBar.stories.tsx @@ -3,7 +3,8 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './IncomingCallBar'; import { IncomingCallBar } from './IncomingCallBar'; import { CallMode } from '../types/Calling'; import { setupI18n } from '../util/setupI18n'; @@ -53,7 +54,7 @@ const groupConversation = getDefaultConversation({ export default { title: 'Components/IncomingCallBar', -}; +} satisfies Meta; export function IncomingDirectCallVideo(): JSX.Element { return ( @@ -66,10 +67,6 @@ export function IncomingDirectCallVideo(): JSX.Element { ); } -IncomingDirectCallVideo.story = { - name: 'Incoming direct call (video)', -}; - export function IncomingDirectCallAudio(): JSX.Element { return ( ); } - -IncomingGroupCallCallingYouAnd4Others.story = { - name: 'Incoming group call (calling you and 4 others)', -}; diff --git a/ts/components/Input.stories.tsx b/ts/components/Input.stories.tsx index 370358fa57..e6b580e901 100644 --- a/ts/components/Input.stories.tsx +++ b/ts/components/Input.stories.tsx @@ -2,10 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState } from 'react'; - -import { text } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './Input'; import { Input } from './Input'; import { setupI18n } from '../util/setupI18n'; @@ -15,7 +13,9 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Input', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const createProps = (overrideProps: Partial = {}): PropsType => ({ disabled: Boolean(overrideProps.disabled), @@ -26,11 +26,8 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ icon: overrideProps.icon, maxLengthCount: overrideProps.maxLengthCount, onChange: action('onChange'), - placeholder: text( - 'placeholder', - overrideProps.placeholder || 'Enter some text here' - ), - value: text('value', overrideProps.value || ''), + placeholder: overrideProps.placeholder ?? 'Enter some text here', + value: overrideProps.value ?? '', whenToShowRemainingCount: overrideProps.whenToShowRemainingCount, }); @@ -55,10 +52,6 @@ export function HasClearButton(): JSX.Element { ); } -HasClearButton.story = { - name: 'hasClearButton', -}; - export function CharacterCount(): JSX.Element { return ( ); } - -SpellcheckDisabled.story = { - name: 'spellcheck disabled', -}; diff --git a/ts/components/Intl.stories.tsx b/ts/components/Intl.stories.tsx index d2dfb2359b..1460c902dd 100644 --- a/ts/components/Intl.stories.tsx +++ b/ts/components/Intl.stories.tsx @@ -1,7 +1,7 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import * as React from 'react'; import type { Props } from './Intl'; @@ -14,7 +14,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Intl', component: Intl, -} as Meta; +} satisfies Meta; const createProps = (overrideProps: Partial = {}): Props => ({ i18n, @@ -24,7 +24,7 @@ const createProps = (overrideProps: Partial = {}): Props => ({ // eslint-disable-next-line max-len // eslint-disable-next-line react/function-component-definition, local-rules/valid-i18n-keys -const Template: Story = args => ; +const Template: StoryFn = args => ; export const NoReplacements = Template.bind({}); NoReplacements.args = createProps({ diff --git a/ts/components/LeftPane.stories.tsx b/ts/components/LeftPane.stories.tsx index 9d5ca9eaa3..f2cabb6279 100644 --- a/ts/components/LeftPane.stories.tsx +++ b/ts/components/LeftPane.stories.tsx @@ -2,10 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; -import { boolean, select } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './LeftPane'; import { LeftPane, LeftPaneMode } from './LeftPane'; import { CaptchaDialog } from './CaptchaDialog'; @@ -31,9 +29,9 @@ import { DialogType } from '../types/Dialogs'; import { SocketStatus } from '../types/SocketStatus'; import { StorybookThemeContext } from '../../.storybook/StorybookThemeContext'; import { - makeFakeLookupConversationWithoutUuid, + makeFakeLookupConversationWithoutServiceId, useUuidFetchState, -} from '../test-both/helpers/fakeLookupConversationWithoutUuid'; +} from '../test-both/helpers/fakeLookupConversationWithoutServiceId'; import type { GroupListItemConversationType } from './conversationList/GroupListItem'; const i18n = setupI18n('en', enMessages); @@ -45,7 +43,9 @@ type OverridePropsType = Partial & { export default { title: 'Components/LeftPane', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const defaultConversations: Array = [ getDefaultConversation({ @@ -126,13 +126,14 @@ const useProps = (overrideProps: OverridePropsType = {}): PropsType => { }; } - const isUpdateDownloaded = boolean('isUpdateDownloaded', false); - const isContactManagementEnabled = boolean( - 'isContactManagementEnabled', - true - ); + const isUpdateDownloaded = false; return { + otherTabsUnreadStats: { + unreadCount: 0, + unreadMentionsCount: 0, + markedUnread: false, + }, clearConversationSearch: action('clearConversationSearch'), clearGroupCreationError: action('clearGroupCreationError'), clearSearch: action('clearSearch'), @@ -143,31 +144,28 @@ const useProps = (overrideProps: OverridePropsType = {}): PropsType => { composeSaveAvatarToDisk: action('composeSaveAvatarToDisk'), createGroup: action('createGroup'), getPreferredBadge: () => undefined, + hasFailedStorySends: false, + hasPendingUpdate: false, i18n, - isMacOS: boolean('isMacOS', false), + isMacOS: false, preferredWidthFromStorage: 320, regionCode: 'US', - challengeStatus: select( - 'challengeStatus', - ['idle', 'required', 'pending'], - 'idle' - ), - crashReportCount: select('challengeReportCount', [0, 1], 0), + challengeStatus: 'idle', + crashReportCount: 0, - hasNetworkDialog: boolean('hasNetworkDialog', false), - hasExpiredDialog: boolean('hasExpiredDialog', false), - hasRelinkDialog: boolean('hasRelinkDialog', false), - hasUpdateDialog: boolean('hasUpdateDialog', false), - unsupportedOSDialogType: select( - 'unsupportedOSDialogType', - ['error', 'warning', undefined], - undefined - ), + hasNetworkDialog: false, + hasExpiredDialog: false, + hasRelinkDialog: false, + hasUpdateDialog: false, + unsupportedOSDialogType: undefined, + usernameCorrupted: false, + usernameLinkCorrupted: false, isUpdateDownloaded, - isContactManagementEnabled, + navTabsCollapsed: false, setChallengeStatus: action('setChallengeStatus'), - lookupConversationWithoutUuid: makeFakeLookupConversationWithoutUuid(), + lookupConversationWithoutServiceId: + makeFakeLookupConversationWithoutServiceId(), showUserNotFoundModal: action('showUserNotFoundModal'), setIsFetchingUUID, showConversation: action('showConversation'), @@ -179,7 +177,6 @@ const useProps = (overrideProps: OverridePropsType = {}): PropsType => { 'onOutgoingVideoCallInConversation' ), removeConversation: action('removeConversation'), - renderMainHeader: () =>
, renderMessageSearchResult: (id: string) => ( { toggleConversationInChooseMembers: action( 'toggleConversationInChooseMembers' ), + toggleNavTabsCollapse: action('toggleNavTabsCollapse'), + toggleProfileEditor: action('toggleProfileEditor'), updateSearchTerm: action('updateSearchTerm'), ...overrideProps, @@ -306,9 +305,41 @@ export function InboxNoConversations(): JSX.Element { ); } -InboxNoConversations.story = { - name: 'Inbox: no conversations', -}; +export function InboxUsernameCorrupted(): JSX.Element { + return ( + + ); +} + +export function InboxUsernameLinkCorrupted(): JSX.Element { + return ( + + ); +} export function InboxOnlyPinnedConversations(): JSX.Element { return ( @@ -327,10 +358,6 @@ export function InboxOnlyPinnedConversations(): JSX.Element { ); } -InboxOnlyPinnedConversations.story = { - name: 'Inbox: only pinned conversations', -}; - export function InboxOnlyNonPinnedConversations(): JSX.Element { return ( ; } -InboxPinnedNonPinnedAndArchivedConversations.story = { - name: 'Inbox: pinned, non-pinned, and archived conversations', -}; - export function SearchNoResultsWhenSearchingEverywhere(): JSX.Element { return ( ( - -); - -_CrashReportDialog.story = { - name: 'Crash report dialog', -}; +export function _CrashReportDialog(): JSX.Element { + return ( + + ); +} export function ChooseGroupMembersPartialPhoneNumber(): JSX.Element { return ( @@ -1037,6 +938,7 @@ export function ChooseGroupMembersPartialPhoneNumber(): JSX.Element { isShowingRecommendedGroupSizeModal: false, isShowingMaximumGroupSizeModal: false, isUsernamesEnabled: true, + ourUsername: undefined, searchTerm: '+1(212) 555', regionCode: 'US', selectedContacts: [], @@ -1046,10 +948,6 @@ export function ChooseGroupMembersPartialPhoneNumber(): JSX.Element { ); } -ChooseGroupMembersPartialPhoneNumber.story = { - name: 'Choose Group Members: Partial phone number', -}; - export function ChooseGroupMembersValidPhoneNumber(): JSX.Element { return ( void; + navTabsCollapsed: boolean; onOutgoingAudioCallInConversation: (conversationId: string) => void; onOutgoingVideoCallInConversation: (conversationId: string) => void; removeConversation: (conversationId: string) => void; @@ -132,10 +137,11 @@ export type PropsType = { startSettingGroupMetadata: () => void; toggleComposeEditingAvatar: () => unknown; toggleConversationInChooseMembers: (conversationId: string) => void; + toggleNavTabsCollapse: (navTabsCollapsed: boolean) => void; + toggleProfileEditor: () => void; updateSearchTerm: (_: string) => void; // Render Props - renderMainHeader: () => JSX.Element; renderMessageSearchResult: (id: string) => JSX.Element; renderNetworkStatus: ( _: Readonly<{ containerWidthBreakpoint: WidthBreakpoint }> @@ -152,9 +158,10 @@ export type PropsType = { renderCaptchaDialog: (props: { onSkip(): void }) => JSX.Element; renderCrashReportDialog: () => JSX.Element; renderExpiredBuildDialog: (_: DialogExpiredBuildPropsType) => JSX.Element; -} & LookupConversationWithoutUuidActionsType; +} & LookupConversationWithoutServiceIdActionsType; export function LeftPane({ + otherTabsUnreadStats, blockConversation, challengeStatus, clearConversationSearch, @@ -169,23 +176,25 @@ export function LeftPane({ createGroup, getPreferredBadge, hasExpiredDialog, + hasFailedStorySends, hasNetworkDialog, + hasPendingUpdate, hasRelinkDialog, hasUpdateDialog, i18n, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, isMacOS, isUpdateDownloaded, - isContactManagementEnabled, modeSpecificProps, + navTabsCollapsed, onOutgoingAudioCallInConversation, onOutgoingVideoCallInConversation, + preferredWidthFromStorage, removeConversation, renderCaptchaDialog, renderCrashReportDialog, renderExpiredBuildDialog, - renderMainHeader, renderMessageSearchResult, renderNetworkStatus, renderUnsupportedOSDialog, @@ -195,6 +204,8 @@ export function LeftPane({ searchInConversation, selectedConversationId, targetedMessageId, + toggleNavTabsCollapse, + toggleProfileEditor, setChallengeStatus, setComposeGroupAvatar, setComposeGroupExpireTimer, @@ -213,14 +224,10 @@ export function LeftPane({ toggleComposeEditingAvatar, toggleConversationInChooseMembers, unsupportedOSDialogType, + usernameCorrupted, + usernameLinkCorrupted, updateSearchTerm, }: PropsType): JSX.Element { - const [preferredWidth, setPreferredWidth] = useState( - // This clamp is present just in case we get a bogus value from storage. - clamp(preferredWidthFromStorage, MIN_WIDTH, MAX_WIDTH) - ); - const [isResizing, setIsResizing] = useState(false); - const previousModeSpecificProps = usePrevious( modeSpecificProps, modeSpecificProps @@ -421,76 +428,6 @@ export function LeftPane({ startSearch, ]); - const requiresFullWidth = helper.requiresFullWidth(); - - useEffect(() => { - if (!isResizing) { - return noop; - } - - const onMouseMove = (event: MouseEvent) => { - let width: number; - - const isRTL = i18n.getLocaleDirection() === 'rtl'; - const x = isRTL ? window.innerWidth - event.clientX : event.clientX; - - if (requiresFullWidth) { - width = Math.max(x, MIN_FULL_WIDTH); - } else if (x < SNAP_WIDTH) { - width = MIN_WIDTH; - } else { - width = clamp(x, MIN_FULL_WIDTH, MAX_WIDTH); - } - setPreferredWidth(Math.min(width, MAX_WIDTH)); - - event.preventDefault(); - }; - - const stopResizing = () => { - setIsResizing(false); - }; - - document.body.addEventListener('mousemove', onMouseMove); - document.body.addEventListener('mouseup', stopResizing); - document.body.addEventListener('mouseleave', stopResizing); - - return () => { - document.body.removeEventListener('mousemove', onMouseMove); - document.body.removeEventListener('mouseup', stopResizing); - document.body.removeEventListener('mouseleave', stopResizing); - }; - }, [i18n, isResizing, requiresFullWidth]); - - useEffect(() => { - if (!isResizing) { - return noop; - } - - document.body.classList.add('is-resizing-left-pane'); - return () => { - document.body.classList.remove('is-resizing-left-pane'); - }; - }, [isResizing]); - - useEffect(() => { - if (isResizing || preferredWidth === preferredWidthFromStorage) { - return; - } - - const timeout = setTimeout(() => { - savePreferredLeftPaneWidth(preferredWidth); - }, 1000); - - return () => { - clearTimeout(timeout); - }; - }, [ - isResizing, - preferredWidth, - preferredWidthFromStorage, - savePreferredLeftPaneWidth, - ]); - const preRowsNode = helper.getPreRowsNode({ clearConversationSearch, clearGroupCreationError, @@ -553,11 +490,12 @@ export function LeftPane({ // It also ensures that we scroll to the top when switching views. const listKey = preRowsNode ? 1 : 0; - const width = getWidthFromPreferredWidth(preferredWidth, { - requiresFullWidth, - }); + const measureRef = useRef(null); + const measureSize = useSizeObserver(measureRef); - const widthBreakpoint = getConversationListWidthBreakpoint(width); + const widthBreakpoint = getNavSidebarWidthBreakpoint( + measureSize?.width ?? preferredWidthFromStorage + ); const commonDialogProps = { i18n, @@ -613,128 +551,198 @@ export function LeftPane({ } } + let maybeBanner: JSX.Element | undefined; + if (usernameCorrupted) { + maybeBanner = ( + + {i18n('icu:LeftPane--corrupted-username--text')} + + ); + } else if (usernameLinkCorrupted) { + maybeBanner = ( + + {i18n('icu:LeftPane--corrupted-username-link--text')} + + ); + } + + if (maybeBanner) { + dialogs.push({ key: 'banner', dialog: maybeBanner }); + } + return ( - + ); } diff --git a/ts/components/LeftPaneBanner.stories.tsx b/ts/components/LeftPaneBanner.stories.tsx new file mode 100644 index 0000000000..95d3735525 --- /dev/null +++ b/ts/components/LeftPaneBanner.stories.tsx @@ -0,0 +1,25 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import React from 'react'; +import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import { LeftPaneBanner, type PropsType } from './LeftPaneBanner'; + +export default { + title: 'Components/LeftPaneBanner', + component: LeftPaneBanner, + argTypes: { + actionText: { control: { type: 'string' } }, + children: { control: { type: 'string' } }, + }, + args: { + actionText: 'Fix now', + children: 'Recoverable issue detected', + onClick: action('onClick'), + }, +} satisfies Meta; + +export function Defaults(args: PropsType): JSX.Element { + return ; +} diff --git a/ts/components/LeftPaneBanner.tsx b/ts/components/LeftPaneBanner.tsx new file mode 100644 index 0000000000..403a9196f8 --- /dev/null +++ b/ts/components/LeftPaneBanner.tsx @@ -0,0 +1,48 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { ReactNode } from 'react'; +import React, { useCallback } from 'react'; + +const BASE_CLASS_NAME = 'LeftPaneBanner'; + +export type PropsType = Readonly<{ + children?: ReactNode; + actionText: string; + onClick: () => void; +}>; + +export function LeftPaneBanner({ + children, + actionText, + onClick, +}: PropsType): JSX.Element { + const onClickWrap = useCallback( + (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + + onClick?.(); + }, + [onClick] + ); + + return ( +
+
{children}
+ +
+ +
+
+ ); +} diff --git a/ts/components/LeftPaneDialog.stories.tsx b/ts/components/LeftPaneDialog.stories.tsx new file mode 100644 index 0000000000..b4e88bbe7a --- /dev/null +++ b/ts/components/LeftPaneDialog.stories.tsx @@ -0,0 +1,134 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import React from 'react'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './LeftPaneDialog'; +import { LeftPaneDialog } from './LeftPaneDialog'; +import { WidthBreakpoint } from './_util'; + +const widths = { + [WidthBreakpoint.Wide]: '400px', + [WidthBreakpoint.Medium]: '300px', + [WidthBreakpoint.Narrow]: '100px', +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function WidthDecorator(Story: any, context: any): JSX.Element { + return ( +
+ +
+ ); +} + +export default { + title: 'Components/LeftPaneDialog', + component: LeftPaneDialog, + decorators: [WidthDecorator], + argTypes: { + type: { + options: [undefined, 'warning', 'error'], + control: { type: 'select' }, + }, + icon: { + options: [undefined, 'update', 'relink', 'network', 'warning'], + control: { type: 'select' }, + }, + title: { + control: { type: 'text' }, + }, + subtitle: { + control: { type: 'text' }, + }, + hoverText: { + control: { type: 'text' }, + }, + hasXButton: { + control: { type: 'boolean' }, + }, + hasAction: { + control: { type: 'boolean' }, + }, + containerWidthBreakpoint: { + options: Object.keys(WidthBreakpoint), + mapping: WidthBreakpoint, + control: { type: 'select' }, + }, + }, + args: { + title: 'Lorem ipsum dolor sit amet', + subtitle: + 'Consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', + hoverText: + 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.', + hasXButton: true, + hasAction: true, + onClick: (): null => null, + clickLabel: 'Click me', + containerWidthBreakpoint: WidthBreakpoint.Wide, + }, +} satisfies Meta; + +export const Update = { + args: { + type: undefined, + icon: 'update', + }, +}; + +export const Warning = { + args: { + type: 'warning', + icon: 'warning', + }, +}; + +export const Error = { + args: { + type: 'error', + icon: 'warning', + }, +}; + +export const Relink = { + args: { + type: undefined, + icon: 'relink', + }, +}; + +export const Network = { + args: { + type: 'warning', + icon: 'network', + }, +}; + +export const NarrowUpdate = { + args: { + type: undefined, + icon: 'update', + containerWidthBreakpoint: WidthBreakpoint.Narrow, + }, +}; + +export const NarrowWarning = { + args: { + type: 'warning', + icon: 'warning', + containerWidthBreakpoint: WidthBreakpoint.Narrow, + }, +}; + +export const NarrowError = { + args: { + type: 'error', + icon: 'warning', + containerWidthBreakpoint: WidthBreakpoint.Narrow, + }, +}; diff --git a/ts/components/LeftPaneDialog.tsx b/ts/components/LeftPaneDialog.tsx index e338a0e34e..bfc12cffe6 100644 --- a/ts/components/LeftPaneDialog.tsx +++ b/ts/components/LeftPaneDialog.tsx @@ -109,7 +109,7 @@ export function LeftPaneDialog({ } let xButton: ReactNode; - if (hasXButton) { + if (hasXButton && containerWidthBreakpoint !== WidthBreakpoint.Narrow) { xButton = (
- )} -
-
- ); -} diff --git a/ts/components/MediaEditor.stories.tsx b/ts/components/MediaEditor.stories.tsx index 0e8adf1778..7ac7928a52 100644 --- a/ts/components/MediaEditor.stories.tsx +++ b/ts/components/MediaEditor.stories.tsx @@ -1,79 +1,66 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; -import { action } from '@storybook/addon-actions'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './MediaEditor'; import { MediaEditor } from './MediaEditor'; import enMessages from '../../_locales/en/messages.json'; import { setupI18n } from '../util/setupI18n'; import { Stickers, installedPacks } from '../test-both/helpers/getStickerPacks'; -import { CompositionTextArea } from './CompositionTextArea'; const i18n = setupI18n('en', enMessages); - -export default { - title: 'Components/MediaEditor', -}; - const IMAGE_1 = '/fixtures/nathan-anderson-316188-unsplash.jpg'; const IMAGE_2 = '/fixtures/tina-rolf-269345-unsplash.jpg'; const IMAGE_3 = '/fixtures/kitten-4-112-112.jpg'; const IMAGE_4 = '/fixtures/snow.jpg'; -const getDefaultProps = (): PropsType => ({ - i18n, - imageSrc: IMAGE_2, - onClose: action('onClose'), - onDone: action('onDone'), - isSending: false, - imageToBlurHash: async () => 'LDA,FDBnm+I=p{tkIUI;~UkpELV]', +export default { + title: 'Components/MediaEditor', + component: MediaEditor, + args: { + getPreferredBadge: () => undefined, + i18n, + imageToBlurHash: input => Promise.resolve(input.toString()), + imageSrc: IMAGE_2, + installedPacks, + isFormattingEnabled: true, + isFormattingFlagEnabled: true, + isFormattingSpoilersFlagEnabled: true, + isSending: false, + onClose: action('onClose'), + onDone: action('onDone'), + onPickEmoji: action('onPickEmoji'), + onTextTooLong: action('onTextTooLong'), + platform: 'darwin', + recentStickers: [Stickers.wide, Stickers.tall, Stickers.abe], + skinTone: 0, + }, +} satisfies Meta; - // StickerButtonProps - installedPacks, - recentStickers: [Stickers.wide, Stickers.tall, Stickers.abe], -}); +// eslint-disable-next-line react/function-component-definition +const Template: StoryFn = args => ; -export function ExtraLarge(): JSX.Element { - return ; -} +export const ExtraLarge = Template.bind({}); -export function Large(): JSX.Element { - return ; -} +export const Large = Template.bind({}); +Large.args = { + imageSrc: IMAGE_1, +}; -export function Smol(): JSX.Element { - return ; -} +export const Smol = Template.bind({}); +Smol.args = { + imageSrc: IMAGE_3, +}; -export function Portrait(): JSX.Element { - return ; -} +export const Portrait = Template.bind({}); +Portrait.args = { + imageSrc: IMAGE_4, +}; -export function Sending(): JSX.Element { - return ; -} - -export function WithCaption(): JSX.Element { - return ( - ( - undefined} - i18n={i18n} - isFormattingEnabled - isFormattingFlagEnabled - isFormattingSpoilersFlagEnabled - onPickEmoji={action('onPickEmoji')} - onSetSkinTone={action('onSetSkinTone')} - onTextTooLong={action('onTextTooLong')} - platform="darwin" - /> - )} - /> - ); -} +export const Sending = Template.bind({}); +Sending.args = { + isSending: true, +}; diff --git a/ts/components/MediaEditor.tsx b/ts/components/MediaEditor.tsx index a97495493d..bb94e87840 100644 --- a/ts/components/MediaEditor.tsx +++ b/ts/components/MediaEditor.tsx @@ -1,30 +1,33 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { useCallback, useEffect, useState } from 'react'; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import classNames from 'classnames'; import { createPortal } from 'react-dom'; import { fabric } from 'fabric'; +import { useSelector } from 'react-redux'; import { get, has, noop } from 'lodash'; -import type { LocalizerType } from '../types/Util'; -import { ThemeType } from '../types/Util'; -import type { MIMEType } from '../types/MIME'; -import { IMAGE_PNG } from '../types/MIME'; -import type { Props as StickerButtonProps } from './stickers/StickerButton'; +import type { + EmojiPickDataType, + Props as EmojiPickerProps, +} from './emoji/EmojiPicker'; +import type { DraftBodyRanges } from '../types/BodyRange'; import type { ImageStateType } from '../mediaEditor/ImageStateType'; - -import * as log from '../logging/log'; -import { Button, ButtonVariant } from './Button'; -import { ContextMenu } from './ContextMenu'; -import { Slider } from './Slider'; -import { StickerButton } from './stickers/StickerButton'; -import { Theme } from '../util/theme'; -import { canvasToBytes } from '../util/canvasToBytes'; +import type { + InputApi, + Props as CompositionInputProps, +} from './CompositionInput'; +import type { LocalizerType } from '../types/Util'; +import type { MIMEType } from '../types/MIME'; +import type { Props as StickerButtonProps } from './stickers/StickerButton'; import type { imageToBlurHash } from '../util/imageToBlurHash'; -import { useFabricHistory } from '../mediaEditor/useFabricHistory'; -import { usePortal } from '../hooks/usePortal'; -import { useUniqueId } from '../hooks/useUniqueId'; import { MediaEditorFabricAnalogTimeSticker } from '../mediaEditor/MediaEditorFabricAnalogTimeSticker'; import { MediaEditorFabricCropRect } from '../mediaEditor/MediaEditorFabricCropRect'; @@ -35,25 +38,37 @@ import { MediaEditorFabricSticker } from '../mediaEditor/MediaEditorFabricSticke import { fabricEffectListener } from '../mediaEditor/fabricEffectListener'; import { getRGBA, getHSL } from '../mediaEditor/util/color'; import { - TextStyle, getTextStyleAttributes, + TextStyle, } from '../mediaEditor/util/getTextStyleAttributes'; -import { AddCaptionModal } from './AddCaptionModal'; -import type { SmartCompositionTextAreaProps } from '../state/smart/CompositionTextArea'; -import { useConfirmDiscard } from '../hooks/useConfirmDiscard'; -import { Spinner } from './Spinner'; -import type { HydratedBodyRangesType } from '../types/BodyRange'; -import { MessageBody } from './conversation/MessageBody'; -import { RenderLocation } from './conversation/MessageTextRenderer'; -import { arrow } from '../util/keyboard'; + +import * as log from '../logging/log'; +import { Button, ButtonVariant } from './Button'; +import { CompositionInput } from './CompositionInput'; +import { ContextMenu } from './ContextMenu'; +import { EmojiButton } from './emoji/EmojiButton'; +import { IMAGE_PNG } from '../types/MIME'; import { SizeObserver } from '../hooks/useSizeObserver'; +import { Slider } from './Slider'; +import { Spinner } from './Spinner'; +import { StickerButton } from './stickers/StickerButton'; +import { Theme } from '../util/theme'; +import { ThemeType } from '../types/Util'; +import { arrow } from '../util/keyboard'; +import { canvasToBytes } from '../util/canvasToBytes'; +import { getConversationSelector } from '../state/selectors/conversations'; +import { hydrateRanges } from '../types/BodyRange'; +import { useConfirmDiscard } from '../hooks/useConfirmDiscard'; +import { useFabricHistory } from '../mediaEditor/useFabricHistory'; +import { usePortal } from '../hooks/usePortal'; +import { useUniqueId } from '../hooks/useUniqueId'; export type MediaEditorResultType = Readonly<{ data: Uint8Array; contentType: MIMEType; blurHash: string; caption?: string; - captionBodyRanges?: HydratedBodyRangesType; + captionBodyRanges?: DraftBodyRanges; }>; export type PropsType = { @@ -65,18 +80,20 @@ export type PropsType = { onClose: () => unknown; onDone: (result: MediaEditorResultType) => unknown; } & Pick & - ( - | { - supportsCaption: true; - renderCompositionTextArea: ( - props: SmartCompositionTextAreaProps - ) => JSX.Element; - } - | { - supportsCaption?: false; - renderCompositionTextArea?: undefined; - } - ); + Pick< + CompositionInputProps, + | 'draftText' + | 'draftBodyRanges' + | 'getPreferredBadge' + | 'isFormattingEnabled' + | 'isFormattingFlagEnabled' + | 'isFormattingSpoilersFlagEnabled' + | 'onPickEmoji' + | 'onTextTooLong' + | 'platform' + | 'sortedGroupMembers' + > & + EmojiPickerProps; const INITIAL_IMAGE_STATE: ImageStateType = { angle: 0, @@ -106,6 +123,12 @@ enum DrawTool { Highlighter = 'Highlighter', } +enum CropPreset { + Freeform = 'Freeform', + Square = 'Square', + Vertical = 'Vertical', +} + type PendingCropType = { left: number; top: number; @@ -128,6 +151,23 @@ export function MediaEditor({ onClose, onDone, + // CompositionInput + draftText, + draftBodyRanges, + getPreferredBadge, + isFormattingEnabled, + isFormattingFlagEnabled, + isFormattingSpoilersFlagEnabled, + onPickEmoji, + onTextTooLong, + platform, + sortedGroupMembers, + + // EmojiPickerProps + onSetSkinTone, + recentEmojis, + skinTone, + // StickerButtonProps installedPacks, recentStickers, @@ -137,19 +177,45 @@ export function MediaEditor({ const [image, setImage] = useState(new Image()); const [isStickerPopperOpen, setIsStickerPopperOpen] = useState(false); + const [isEmojiPopperOpen, setEmojiPopperOpen] = useState(false); - const [caption, setCaption] = useState(''); + const [caption, setCaption] = useState(draftText ?? ''); const [captionBodyRanges, setCaptionBodyRanges] = useState< - HydratedBodyRangesType | undefined - >(); + DraftBodyRanges | undefined + >(draftBodyRanges); - const [showAddCaptionModal, setShowAddCaptionModal] = useState(false); + const conversationSelector = useSelector(getConversationSelector); + const hydratedBodyRanges = useMemo( + () => hydrateRanges(captionBodyRanges, conversationSelector), + [captionBodyRanges, conversationSelector] + ); + + const inputApiRef = useRef(); + + const closeEmojiPickerAndFocusComposer = useCallback(() => { + if (inputApiRef.current) { + inputApiRef.current.focus(); + } + setEmojiPopperOpen(false); + }, [inputApiRef]); + + const insertEmoji = useCallback( + (e: EmojiPickDataType) => { + if (inputApiRef.current) { + inputApiRef.current.insertEmoji(e); + onPickEmoji(e); + } + }, + [inputApiRef, onPickEmoji] + ); const canvasId = useUniqueId(); const [imageState, setImageState] = useState(INITIAL_IMAGE_STATE); + const [cropPreset, setCropPreset] = useState(CropPreset.Freeform); + // History state const { canRedo, canUndo, redoIfPossible, takeSnapshot, undoIfPossible } = useFabricHistory({ @@ -199,8 +265,8 @@ export function MediaEditor({ const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard(i18n); const onTryClose = useCallback(() => { - confirmDiscardIf(caption !== '' || Boolean(image), onClose); - }, [confirmDiscardIf, caption, image, onClose]); + confirmDiscardIf(canUndo, onClose); + }, [confirmDiscardIf, canUndo, onClose]); // Keyboard support useEffect(() => { @@ -228,6 +294,12 @@ export function MediaEditor({ [ ev => ev.key === 'Escape', () => { + // if the emoji popper is open, + // it will use the escape key to close itself + if (isEmojiPopperOpen) { + return; + } + // close window if the user is not in the middle of something if (editMode === undefined) { // if the stickers popper is open, @@ -377,6 +449,7 @@ export function MediaEditor({ }, [ fabricCanvas, editMode, + isEmojiPopperOpen, isStickerPopperOpen, onTryClose, redoIfPossible, @@ -523,6 +596,40 @@ export function MediaEditor({ } }, [fabricCanvas, sliderValue, textStyle]); + useEffect(() => { + if (!fabricCanvas) { + return; + } + + const rect = fabricCanvas.getObjects().find(obj => { + return obj instanceof MediaEditorFabricCropRect; + }); + + if (!rect) { + return; + } + + const PADDING = MediaEditorFabricCropRect.PADDING / zoom; + let height = + imageState.height - PADDING * Math.max(440 / imageState.height, 2); + let width = + imageState.width - PADDING * Math.max(440 / imageState.width, 2); + + if (cropPreset === CropPreset.Square) { + const size = Math.min(height, width); + height = size; + width = size; + } else if (cropPreset === CropPreset.Vertical) { + width = height * 0.5625; + } + + rect.set({ height, width, scaleX: 1, scaleY: 1 }); + fabricCanvas.viewportCenterObject(rect); + rect.setCoords(); + + setCanCrop(true); + }, [cropPreset, fabricCanvas, imageState.height, imageState.width, zoom]); + // Create the CroppingRect useEffect(() => { if (!fabricCanvas) { @@ -632,148 +739,159 @@ export function MediaEditor({ return null; } - let tooling: JSX.Element | undefined; + let toolElement: JSX.Element | undefined; if (editMode === EditMode.Text) { - tooling = ( + toolElement = ( <> - - setTextStyle(TextStyle.Regular), - value: TextStyle.Regular, - }, - { - icon: 'MediaEditor__icon--text-highlight', - label: i18n('icu:MediaEditor__text--highlight'), - onClick: () => setTextStyle(TextStyle.Highlight), - value: TextStyle.Highlight, - }, - { - icon: 'MediaEditor__icon--text-outline', - label: i18n('icu:MediaEditor__text--outline'), - onClick: () => setTextStyle(TextStyle.Outline), - value: TextStyle.Outline, - }, - ]} - moduleClassName={classNames('MediaEditor__tools__tool', { - 'MediaEditor__tools__button--text-regular': - textStyle === TextStyle.Regular, - 'MediaEditor__tools__button--text-highlight': - textStyle === TextStyle.Highlight, - 'MediaEditor__tools__button--text-outline': - textStyle === TextStyle.Outline, - })} - theme={Theme.Dark} - value={textStyle} - /> - + const activeObject = fabricCanvas?.getActiveObject(); + if (activeObject instanceof MediaEditorFabricIText) { + activeObject.exitEditing(); + } + }} + theme={Theme.Dark} + variant={ButtonVariant.Secondary} + > + {i18n('icu:done')} + +
); } else if (editMode === EditMode.Draw) { - tooling = ( + toolElement = ( <> - - setDrawTool(DrawTool.Pen), - value: DrawTool.Pen, - }, - { - icon: 'MediaEditor__icon--draw-highlighter', - label: i18n('icu:MediaEditor__draw--highlighter'), - onClick: () => setDrawTool(DrawTool.Highlighter), - value: DrawTool.Highlighter, - }, - ]} - moduleClassName={classNames('MediaEditor__tools__tool', { - 'MediaEditor__tools__button--draw-pen': drawTool === DrawTool.Pen, - 'MediaEditor__tools__button--draw-highlighter': - drawTool === DrawTool.Highlighter, - })} - theme={Theme.Dark} - value={drawTool} - /> - setDrawWidth(DrawWidth.Thin), - value: DrawWidth.Thin, - }, - { - icon: 'MediaEditor__icon--width-regular', - label: i18n('icu:MediaEditor__draw--regular'), - onClick: () => setDrawWidth(DrawWidth.Regular), - value: DrawWidth.Regular, - }, - { - icon: 'MediaEditor__icon--width-medium', - label: i18n('icu:MediaEditor__draw--medium'), - onClick: () => setDrawWidth(DrawWidth.Medium), - value: DrawWidth.Medium, - }, - { - icon: 'MediaEditor__icon--width-heavy', - label: i18n('icu:MediaEditor__draw--heavy'), - onClick: () => setDrawWidth(DrawWidth.Heavy), - value: DrawWidth.Heavy, - }, - ]} - moduleClassName={classNames('MediaEditor__tools__tool', { - 'MediaEditor__tools__button--width-thin': - drawWidth === DrawWidth.Thin, - 'MediaEditor__tools__button--width-regular': - drawWidth === DrawWidth.Regular, - 'MediaEditor__tools__button--width-medium': - drawWidth === DrawWidth.Medium, - 'MediaEditor__tools__button--width-heavy': - drawWidth === DrawWidth.Heavy, - })} - theme={Theme.Dark} - value={drawWidth} - /> - +
+
+
+ + setDrawTool(DrawTool.Pen), + value: DrawTool.Pen, + }, + { + icon: 'MediaEditor__icon--draw-highlighter', + label: i18n('icu:MediaEditor__draw--highlighter'), + onClick: () => setDrawTool(DrawTool.Highlighter), + value: DrawTool.Highlighter, + }, + ]} + moduleClassName={classNames('MediaEditor__toolbar__tool', { + 'MediaEditor__toolbar__button--draw-pen': + drawTool === DrawTool.Pen, + 'MediaEditor__toolbar__button--draw-highlighter': + drawTool === DrawTool.Highlighter, + })} + theme={Theme.Dark} + value={drawTool} + /> + setDrawWidth(DrawWidth.Thin), + value: DrawWidth.Thin, + }, + { + icon: 'MediaEditor__icon--width-regular', + label: i18n('icu:MediaEditor__draw--regular'), + onClick: () => setDrawWidth(DrawWidth.Regular), + value: DrawWidth.Regular, + }, + { + icon: 'MediaEditor__icon--width-medium', + label: i18n('icu:MediaEditor__draw--medium'), + onClick: () => setDrawWidth(DrawWidth.Medium), + value: DrawWidth.Medium, + }, + { + icon: 'MediaEditor__icon--width-heavy', + label: i18n('icu:MediaEditor__draw--heavy'), + onClick: () => setDrawWidth(DrawWidth.Heavy), + value: DrawWidth.Heavy, + }, + ]} + moduleClassName={classNames('MediaEditor__toolbar__tool', { + 'MediaEditor__toolbar__button--width-thin': + drawWidth === DrawWidth.Thin, + 'MediaEditor__toolbar__button--width-regular': + drawWidth === DrawWidth.Regular, + 'MediaEditor__toolbar__button--width-medium': + drawWidth === DrawWidth.Medium, + 'MediaEditor__toolbar__button--width-heavy': + drawWidth === DrawWidth.Heavy, + })} + theme={Theme.Dark} + value={drawWidth} + /> +
+ +
); } else if (editMode === EditMode.Crop) { @@ -784,132 +902,215 @@ export function MediaEditor({ imageState.flipY || imageState.angle !== 0; - tooling = ( + toolElement = ( <> - - + + +
+
+ +
+
+ + setImageState(newImageState); + moveFabricObjectsForCrop(fabricCanvas, pendingCrop); + takeSnapshot('crop', newImageState); + setEditMode(undefined); + setCropPreset(CropPreset.Freeform); + }} + theme={Theme.Dark} + variant={ButtonVariant.Secondary} + > + {i18n('icu:done')} + +
); } return createPortal(
+
+
+ - - {showAddCaptionModal && ( - { - setCaption(messageText.trim()); - setCaptionBodyRanges(bodyRanges); - setShowAddCaptionModal(false); - }} - onClose={() => setShowAddCaptionModal(false)} - RenderCompositionTextArea={props.renderCompositionTextArea} - theme={ThemeType.dark} - /> - )} -
- ) : ( -
- )} - - )} -
- -
-
+
+
+ { + setCaptionBodyRanges(bodyRanges); + setCaption(messageText); + }} + onPickEmoji={onPickEmoji} + onSubmit={noop} + onTextTooLong={onTextTooLong} + placeholder={i18n('icu:MediaEditor__input-placeholder')} + platform={platform} + sendCounter={0} + sortedGroupMembers={sortedGroupMembers} + theme={ThemeType.dark} + > + setEmojiPopperOpen(true)} + onClose={closeEmojiPickerAndFocusComposer} + recentEmojis={recentEmojis} + skinTone={skinTone} + onSetSkinTone={onSetSkinTone} + /> + +
+
- -
+ }} + theme={Theme.Dark} + variant={ButtonVariant.Primary} + > + {isSending ? ( + + ) : ( + doneButtonLabel || i18n('icu:save') + )} + +
+ + )}
{confirmDiscardModal}
, diff --git a/ts/components/MediaQualitySelector.stories.tsx b/ts/components/MediaQualitySelector.stories.tsx index a1277f3516..61ba742e1e 100644 --- a/ts/components/MediaQualitySelector.stories.tsx +++ b/ts/components/MediaQualitySelector.stories.tsx @@ -2,10 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; - import { action } from '@storybook/addon-actions'; -import { boolean } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import type { PropsType } from './MediaQualitySelector'; import { MediaQualitySelector } from './MediaQualitySelector'; @@ -13,14 +11,16 @@ import { setupI18n } from '../util/setupI18n'; export default { title: 'Components/MediaQualitySelector', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const i18n = setupI18n('en', enMessages); const createProps = (overrideProps: Partial = {}): PropsType => ({ conversationId: 'abc123', i18n, - isHighQuality: boolean('isHighQuality', Boolean(overrideProps.isHighQuality)), + isHighQuality: overrideProps.isHighQuality ?? false, onSelectQuality: action('onSelectQuality'), }); diff --git a/ts/components/MiniPlayer.stories.tsx b/ts/components/MiniPlayer.stories.tsx index 7c5e58cc89..f1570e3b1d 100644 --- a/ts/components/MiniPlayer.stories.tsx +++ b/ts/components/MiniPlayer.stories.tsx @@ -2,6 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useEffect, useState } from 'react'; +import type { Meta } from '@storybook/react'; +import type { Props } from './MiniPlayer'; import { MiniPlayer, PlayerState } from './MiniPlayer'; import { setupI18n } from '../util/setupI18n'; @@ -15,7 +17,7 @@ audio.src = '/fixtures/incompetech-com-Agnus-Dei-X.mp3'; export default { title: 'components/MiniPlayer', component: MiniPlayer, -}; +} satisfies Meta; export function Default(): JSX.Element { const [active, setActive] = useState(false); diff --git a/ts/components/Modal.stories.tsx b/ts/components/Modal.stories.tsx index 267fdffeb5..6a4034febc 100644 --- a/ts/components/Modal.stories.tsx +++ b/ts/components/Modal.stories.tsx @@ -3,19 +3,19 @@ import React from 'react'; import { noop } from 'lodash'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; import { Button } from './Button'; +import type { ModalPropsType } from './Modal'; import { Modal } from './Modal'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Modal', -}; +} satisfies Meta; const onClose = action('onClose'); @@ -30,10 +30,6 @@ export function BareBonesShort(): JSX.Element { ); } -BareBonesShort.story = { - name: 'Bare bones, short', -}; - export function BareBonesLong(): JSX.Element { return ( @@ -45,10 +41,6 @@ export function BareBonesLong(): JSX.Element { ); } -BareBonesLong.story = { - name: 'Bare bones, long', -}; - export function BareBonesLongWithButton(): JSX.Element { return ( ); } - -WithBackButton.story = { - name: 'Back Button', -}; diff --git a/ts/components/Modal.tsx b/ts/components/Modal.tsx index 5bba0990a6..6271836138 100644 --- a/ts/components/Modal.tsx +++ b/ts/components/Modal.tsx @@ -18,6 +18,7 @@ import * as log from '../logging/log'; import { isOverflowing, isScrolled, + isScrolledToBottom, useScrollObserver, } from '../hooks/useSizeObserver'; @@ -29,6 +30,7 @@ type PropsType = { hasFooterDivider?: boolean; i18n: LocalizerType; modalFooter?: JSX.Element; + modalHeaderChildren?: ReactNode; moduleClassName?: string; onBackButtonClick?: () => unknown; onClose?: () => void; @@ -51,6 +53,7 @@ export function Modal({ hasXButton, i18n, modalFooter, + modalHeaderChildren, moduleClassName, noMouseClose, onBackButtonClick, @@ -121,6 +124,7 @@ export function Modal({ hasXButton={hasXButton} i18n={i18n} modalFooter={modalFooter} + modalHeaderChildren={modalHeaderChildren} moduleClassName={moduleClassName} onBackButtonClick={onBackButtonClick} onClose={close} @@ -161,6 +165,7 @@ export function ModalPage({ hasXButton, i18n, modalFooter, + modalHeaderChildren, moduleClassName, onBackButtonClick, onClose, @@ -175,13 +180,17 @@ export function ModalPage({ const bodyInnerRef = useRef(null); const [scrolled, setScrolled] = useState(false); + const [scrolledToBottom, setScrolledToBottom] = useState(false); const [hasOverflow, setHasOverflow] = useState(false); - const hasHeader = Boolean(hasXButton || title || onBackButtonClick); + const hasHeader = Boolean( + hasXButton || title || modalHeaderChildren || onBackButtonClick + ); const getClassName = getClassNamesFor(BASE_CLASS_NAME, moduleClassName); useScrollObserver(bodyRef, bodyInnerRef, scroll => { setScrolled(isScrolled(scroll)); + setScrolledToBottom(isScrolledToBottom(scroll)); setHasOverflow(isOverflowing(scroll)); }); @@ -213,43 +222,47 @@ export function ModalPage({ : null )} > - {onBackButtonClick && ( -
+ {modalHeaderChildren}
)}
; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const NoStories = Template.bind({}); NoStories.args = { myStories: [], }; -NoStories.story = { - name: 'No Stories', -}; -const interactionTest: PlayFunction = async ({ +const interactionTest: PlayFunction = async ({ args, canvasElement, }) => { @@ -76,7 +59,7 @@ const interactionTest: PlayFunction = async ({ await userEvent.click(btnDownload); await expect(args.onSave).toHaveBeenCalled(); - const [btnBack] = canvas.getAllByLabelText('Back'); + const btnBack = canvas.getByText('Back'); await userEvent.click(btnBack); await expect(args.onBack).toHaveBeenCalled(); @@ -94,9 +77,6 @@ SingleListStories.args = { myStories: [getFakeMyStory(MY_STORY_ID)], }; SingleListStories.play = interactionTest; -SingleListStories.story = { - name: 'One distribution list', -}; export const MultiListStories = Template.bind({}); MultiListStories.args = { @@ -107,9 +87,6 @@ MultiListStories.args = { ], }; MultiListStories.play = interactionTest; -MultiListStories.story = { - name: 'Multiple distribution lists', -}; export const FailedSentStory = Template.bind({}); { diff --git a/ts/components/MyStories.tsx b/ts/components/MyStories.tsx index 772a2e4e2a..51c94e64d3 100644 --- a/ts/components/MyStories.tsx +++ b/ts/components/MyStories.tsx @@ -9,6 +9,7 @@ import { StoryViewModeType, } from '../types/Stories'; import type { LocalizerType } from '../types/Util'; +import { ThemeType } from '../types/Util'; import type { ViewStoryActionCreatorType } from '../state/ducks/stories'; import { ConfirmationDialog } from './ConfirmationDialog'; import { ContextMenu } from './ContextMenu'; @@ -18,23 +19,37 @@ import { StoryImage } from './StoryImage'; import { Theme } from '../util/theme'; import { resolveStorySendStatus } from '../util/resolveStorySendStatus'; import { useRetryStorySend } from '../hooks/useRetryStorySend'; +import { NavSidebar } from './NavSidebar'; +import type { UnreadStats } from '../util/countUnreadStats'; export type PropsType = { i18n: LocalizerType; + otherTabsUnreadStats: UnreadStats; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + navTabsCollapsed: boolean; myStories: Array; onBack: () => unknown; onDelete: (story: StoryViewType) => unknown; onForward: (storyId: string) => unknown; onSave: (story: StoryViewType) => unknown; onMediaPlaybackStart: () => void; + onToggleNavTabsCollapse: (navTabsCollapsed: boolean) => void; queueStoryDownload: (storyId: string) => unknown; retryMessageSend: (messageId: string) => unknown; viewStory: ViewStoryActionCreatorType; hasViewReceiptSetting: boolean; + preferredLeftPaneWidth: number; + savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void; + theme: ThemeType; }; export function MyStories({ i18n, + otherTabsUnreadStats, + hasFailedStorySends, + hasPendingUpdate, + navTabsCollapsed, myStories, onBack, onDelete, @@ -45,6 +60,10 @@ export function MyStories({ viewStory, hasViewReceiptSetting, onMediaPlaybackStart, + onToggleNavTabsCollapse, + preferredLeftPaneWidth, + savePreferredLeftPaneWidth, + theme, }: PropsType): JSX.Element { const [confirmDeleteStory, setConfirmDeleteStory] = useState< StoryViewType | undefined @@ -68,50 +87,54 @@ export function MyStories({ {i18n('icu:MyStories__delete')} )} -
-
-
- {myStories.map(list => ( -
-
- + +
+ {myStories.map(list => ( +
+
+ +
+ {list.stories.map(story => ( + + ))}
- {list.stories.map(story => ( - - ))} -
- ))} -
- {!myStories.length && ( -
- {i18n('icu:Stories__list-empty')} + ))}
- )} + {!myStories.length && ( +
+ {i18n('icu:Stories__list-empty')} +
+ )} + ); } @@ -126,6 +149,7 @@ type StorySentPropsType = Pick< | 'retryMessageSend' | 'viewStory' | 'onMediaPlaybackStart' + | 'theme' > & { setConfirmDeleteStory: (_: StoryViewType | undefined) => unknown; story: StoryViewType; @@ -141,6 +165,7 @@ function StorySent({ retryMessageSend, setConfirmDeleteStory, story, + theme, viewStory, }: StorySentPropsType): JSX.Element { const sendStatus = resolveStorySendStatus(story.sendState ?? []); @@ -269,7 +294,7 @@ function StorySent({ }, ]} moduleClassName="MyStories__story__more" - theme={Theme.Dark} + theme={theme === ThemeType.dark ? Theme.Dark : Theme.Light} />
); diff --git a/ts/components/MyStoryButton.stories.tsx b/ts/components/MyStoryButton.stories.tsx index b49b3b0577..c4589f0e24 100644 --- a/ts/components/MyStoryButton.stories.tsx +++ b/ts/components/MyStoryButton.stories.tsx @@ -1,12 +1,13 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, ReactFramework, Story } from '@storybook/react'; +import type { Meta, ReactRenderer, StoryFn } from '@storybook/react'; import type { PlayFunction } from '@storybook/csf'; import React from 'react'; -import { expect } from '@storybook/jest'; +import { expect, jest } from '@storybook/jest'; import { within, userEvent } from '@storybook/testing-library'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './MyStoryButton'; import enMessages from '../../_locales/en/messages.json'; import { MyStoryButton } from './MyStoryButton'; @@ -21,27 +22,21 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/MyStoriesButton', component: MyStoryButton, - argTypes: { - i18n: { - defaultValue: i18n, - }, - me: { - defaultValue: getDefaultConversation(), - }, - myStories: { - defaultValue: [getFakeMyStory()], - }, - onAddStory: { action: true }, - onClick: { action: true }, - queueStoryDownload: { action: true }, - showToast: { action: true }, + args: { + i18n, + me: getDefaultConversation(), + myStories: [getFakeMyStory()], + onAddStory: jest.fn(action('onAddStory')), + onClick: jest.fn(action('onClick')), + queueStoryDownload: action('queueStoryDownload'), + showToast: action('showToast'), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; -const interactionTest: PlayFunction = async ({ +const interactionTest: PlayFunction = async ({ args, canvasElement, }) => { @@ -51,40 +46,34 @@ const interactionTest: PlayFunction = async ({ const textStory = canvas.getByText('Text story'); await userEvent.click(textStory); await expect(args.onAddStory).toHaveBeenCalled(); - const btnStory = canvas.getByText('My Stories'); - await userEvent.click(btnStory); - await expect(args.onClick).toHaveBeenCalled(); + if (args.myStories.length > 0) { + const btnStory = canvas.getByText('My Stories'); + await userEvent.click(btnStory); + await expect(args.onClick).toHaveBeenCalled(); + } }; export const NoStory = Template.bind({}); NoStory.args = { myStories: [], }; -NoStory.story = { - name: 'No Story', -}; + NoStory.play = interactionTest; export const OneStory = Template.bind({}); OneStory.args = {}; -OneStory.story = { - name: 'One Story', -}; + OneStory.play = interactionTest; export const ManyStories = Template.bind({}); ManyStories.args = { myStories: [getFakeMyStory(), getFakeMyStory()], }; -ManyStories.story = { - name: 'Many Stories', -}; + ManyStories.play = interactionTest; export const SendingStory = Template.bind({}); -SendingStory.story = { - name: 'Sending Story', -}; + { const myStory = getFakeMyStory(); SendingStory.args = { @@ -115,9 +104,7 @@ SendingStory.story = { SendingStory.play = interactionTest; export const FailedSendStory = Template.bind({}); -FailedSendStory.story = { - name: 'Failed Send Story', -}; + { const myStory = getFakeMyStory(); FailedSendStory.args = { diff --git a/ts/components/NavSidebar.tsx b/ts/components/NavSidebar.tsx new file mode 100644 index 0000000000..8f69609da6 --- /dev/null +++ b/ts/components/NavSidebar.tsx @@ -0,0 +1,231 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { KeyboardEventHandler, MouseEventHandler, ReactNode } from 'react'; +import React, { useEffect, useState } from 'react'; +import classNames from 'classnames'; +import { useMove } from 'react-aria'; +import { NavTabsToggle } from './NavTabs'; +import type { LocalizerType } from '../types/I18N'; +import { + MAX_WIDTH, + MIN_FULL_WIDTH, + MIN_WIDTH, + getWidthFromPreferredWidth, +} from '../util/leftPaneWidth'; +import { WidthBreakpoint, getNavSidebarWidthBreakpoint } from './_util'; +import type { UnreadStats } from '../util/countUnreadStats'; + +export function NavSidebarActionButton({ + icon, + label, + onClick, + onKeyDown, +}: { + icon: ReactNode; + label: ReactNode; + onClick: MouseEventHandler; + onKeyDown?: KeyboardEventHandler; +}): JSX.Element { + return ( + + ); +} + +export type NavSidebarProps = Readonly<{ + actions?: ReactNode; + children: ReactNode; + i18n: LocalizerType; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + hideHeader?: boolean; + navTabsCollapsed: boolean; + onBack?: (() => void) | null; + onToggleNavTabsCollapse(navTabsCollapsed: boolean): void; + preferredLeftPaneWidth: number; + requiresFullWidth: boolean; + savePreferredLeftPaneWidth: (width: number) => void; + title: string; + otherTabsUnreadStats: UnreadStats; +}>; + +enum DragState { + INITIAL, + DRAGGING, + DRAGEND, +} + +export function NavSidebar({ + actions, + children, + hideHeader, + i18n, + hasFailedStorySends, + hasPendingUpdate, + navTabsCollapsed, + onBack, + onToggleNavTabsCollapse, + preferredLeftPaneWidth, + requiresFullWidth, + savePreferredLeftPaneWidth, + title, + otherTabsUnreadStats, +}: NavSidebarProps): JSX.Element { + const isRTL = i18n.getLocaleDirection() === 'rtl'; + const [dragState, setDragState] = useState(DragState.INITIAL); + + const [preferredWidth, setPreferredWidth] = useState(() => { + return getWidthFromPreferredWidth(preferredLeftPaneWidth, { + requiresFullWidth, + }); + }); + + const width = getWidthFromPreferredWidth(preferredWidth, { + requiresFullWidth, + }); + + const widthBreakpoint = getNavSidebarWidthBreakpoint(width); + + // `useMove` gives us keyboard and mouse dragging support. + const { moveProps } = useMove({ + onMoveStart() { + setDragState(DragState.DRAGGING); + }, + onMoveEnd() { + setDragState(DragState.DRAGEND); + }, + onMove(event) { + const { shiftKey, pointerType } = event; + const deltaX = isRTL ? -event.deltaX : event.deltaX; + const isKeyboard = pointerType === 'keyboard'; + const increment = isKeyboard && shiftKey ? 10 : 1; + setPreferredWidth(prevWidth => { + // Jump minimize for keyboard users + if (isKeyboard && prevWidth === MIN_FULL_WIDTH && deltaX < 0) { + return MIN_WIDTH; + } + // Jump maximize for keyboard users + if (isKeyboard && prevWidth === MIN_WIDTH && deltaX > 0) { + return MIN_FULL_WIDTH; + } + return prevWidth + deltaX * increment; + }); + }, + }); + + useEffect(() => { + // Save the preferred width when the drag ends. We can't do this in onMoveEnd + // because the width is not updated yet. + if (dragState === DragState.DRAGEND) { + setPreferredWidth(width); + savePreferredLeftPaneWidth(width); + setDragState(DragState.INITIAL); + } + }, [ + dragState, + preferredLeftPaneWidth, + preferredWidth, + savePreferredLeftPaneWidth, + width, + ]); + + useEffect(() => { + // This effect helps keep the pointer `col-resize` even when you drag past the handle. + const className = 'NavSidebar__document--draggingHandle'; + if (dragState === DragState.DRAGGING) { + document.body.classList.add(className); + return () => { + document.body.classList.remove(className); + }; + } + return undefined; + }, [dragState]); + + return ( +
+ {!hideHeader && ( +
+ {onBack == null && navTabsCollapsed && ( + + )} +
+ {onBack != null && ( + + )} +

+ {title} +

+ {actions && ( +
{actions}
+ )} +
+
+ )} + +
{children}
+ + {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props -- See https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/separator_role#focusable_separator */} +
+
+ ); +} + +export function NavSidebarSearchHeader({ + children, +}: { + children: ReactNode; +}): JSX.Element { + return
{children}
; +} diff --git a/ts/components/NavTabs.tsx b/ts/components/NavTabs.tsx new file mode 100644 index 0000000000..0db6eb300f --- /dev/null +++ b/ts/components/NavTabs.tsx @@ -0,0 +1,410 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { Key } from 'react'; +import React from 'react'; +import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'react-aria-components'; +import classNames from 'classnames'; +import { Avatar, AvatarSize } from './Avatar'; +import type { LocalizerType, ThemeType } from '../types/Util'; +import type { ConversationType } from '../state/ducks/conversations'; +import type { BadgeType } from '../badges/types'; +import { NavTab } from '../state/ducks/nav'; +import { Tooltip, TooltipPlacement } from './Tooltip'; +import { Theme } from '../util/theme'; +import type { UnreadStats } from '../util/countUnreadStats'; +import { ContextMenu } from './ContextMenu'; + +type NavTabsItemBadgesProps = Readonly<{ + i18n: LocalizerType; + hasError?: boolean; + hasPendingUpdate?: boolean; + unreadStats: UnreadStats | null; +}>; + +function NavTabsItemBadges({ + i18n, + hasError, + hasPendingUpdate, + unreadStats, +}: NavTabsItemBadgesProps) { + if (hasError) { + return ( + + + {i18n('icu:NavTabs__ItemIconLabel--HasError')} + + ! + + ); + } + + if (hasPendingUpdate) { + return
; + } + + if (unreadStats != null) { + if (unreadStats.unreadCount > 0) { + return ( + + + {i18n('icu:NavTabs__ItemIconLabel--UnreadCount', { + count: unreadStats.unreadCount, + })} + + {unreadStats.unreadCount} + + ); + } + + if (unreadStats.markedUnread) { + return ( + + + {i18n('icu:NavTabs__ItemIconLabel--MarkedUnread')} + + + ); + } + } + + return null; +} + +type NavTabProps = Readonly<{ + i18n: LocalizerType; + iconClassName: string; + id: NavTab; + hasError?: boolean; + label: string; + unreadStats: UnreadStats | null; +}>; + +function NavTabsItem({ + i18n, + iconClassName, + id, + label, + unreadStats, + hasError, +}: NavTabProps) { + const isRTL = i18n.getLocaleDirection() === 'rtl'; + return ( + + {label} + + + + + + + + + + ); +} + +export type NavTabPanelProps = Readonly<{ + otherTabsUnreadStats: UnreadStats; + collapsed: boolean; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + onToggleCollapse(collapsed: boolean): void; +}>; + +export type NavTabsToggleProps = Readonly<{ + otherTabsUnreadStats: UnreadStats | null; + i18n: LocalizerType; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + navTabsCollapsed: boolean; + onToggleNavTabsCollapse(navTabsCollapsed: boolean): void; +}>; + +export function NavTabsToggle({ + i18n, + hasFailedStorySends, + hasPendingUpdate, + navTabsCollapsed, + otherTabsUnreadStats, + onToggleNavTabsCollapse, +}: NavTabsToggleProps): JSX.Element { + function handleToggle() { + onToggleNavTabsCollapse(!navTabsCollapsed); + } + const label = navTabsCollapsed + ? i18n('icu:NavTabsToggle__showTabs') + : i18n('icu:NavTabsToggle__hideTabs'); + const isRTL = i18n.getLocaleDirection() === 'rtl'; + return ( + + ); +} + +export type NavTabsProps = Readonly<{ + badge: BadgeType | undefined; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + i18n: LocalizerType; + me: ConversationType; + navTabsCollapsed: boolean; + onShowSettings: () => void; + onStartUpdate: () => unknown; + onNavTabSelected(tab: NavTab): void; + onToggleNavTabsCollapse(collapsed: boolean): void; + onToggleProfileEditor: () => void; + renderCallsTab(props: NavTabPanelProps): JSX.Element; + renderChatsTab(props: NavTabPanelProps): JSX.Element; + renderStoriesTab(props: NavTabPanelProps): JSX.Element; + selectedNavTab: NavTab; + storiesEnabled: boolean; + theme: ThemeType; + unreadCallsCount: number; + unreadConversationsStats: UnreadStats; + unreadStoriesCount: number; +}>; + +export function NavTabs({ + badge, + hasFailedStorySends, + hasPendingUpdate, + i18n, + me, + navTabsCollapsed, + onShowSettings, + onStartUpdate, + onNavTabSelected, + onToggleNavTabsCollapse, + onToggleProfileEditor, + renderCallsTab, + renderChatsTab, + renderStoriesTab, + selectedNavTab, + storiesEnabled, + theme, + unreadCallsCount, + unreadConversationsStats, + unreadStoriesCount, +}: NavTabsProps): JSX.Element { + function handleSelectionChange(key: Key) { + onNavTabSelected(key as NavTab); + } + + const isRTL = i18n.getLocaleDirection() === 'rtl'; + + return ( + + + + + {renderChatsTab} + + + {renderCallsTab} + + + {renderStoriesTab} + + + + ); +} diff --git a/ts/components/NewlyCreatedGroupInvitedContactsDialog.stories.tsx b/ts/components/NewlyCreatedGroupInvitedContactsDialog.stories.tsx index a503479024..c4c458e932 100644 --- a/ts/components/NewlyCreatedGroupInvitedContactsDialog.stories.tsx +++ b/ts/components/NewlyCreatedGroupInvitedContactsDialog.stories.tsx @@ -5,6 +5,8 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './NewlyCreatedGroupInvitedContactsDialog'; import { NewlyCreatedGroupInvitedContactsDialog } from './NewlyCreatedGroupInvitedContactsDialog'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -21,7 +23,7 @@ const conversations: Array = [ export default { title: 'Components/NewlyCreatedGroupInvitedContactsDialog', -}; +} satisfies Meta; export function OneContact(): JSX.Element { return ( @@ -35,10 +37,6 @@ export function OneContact(): JSX.Element { ); } -OneContact.story = { - name: 'One contact', -}; - export function TwoContacts(): JSX.Element { return ( ); } - -TwoContacts.story = { - name: 'Two contacts', -}; diff --git a/ts/components/NewlyCreatedGroupInvitedContactsDialog.tsx b/ts/components/NewlyCreatedGroupInvitedContactsDialog.tsx index e0c17032d7..51887d427a 100644 --- a/ts/components/NewlyCreatedGroupInvitedContactsDialog.tsx +++ b/ts/components/NewlyCreatedGroupInvitedContactsDialog.tsx @@ -12,7 +12,7 @@ import { ContactName } from './conversation/ContactName'; import { GroupDialog } from './GroupDialog'; import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser'; -type PropsType = { +export type PropsType = { contacts: Array; getPreferredBadge: PreferredBadgeSelectorType; i18n: LocalizerType; diff --git a/ts/components/OutgoingGiftBadgeModal.stories.tsx b/ts/components/OutgoingGiftBadgeModal.stories.tsx index 8c9e22d44a..d5a85f5eab 100644 --- a/ts/components/OutgoingGiftBadgeModal.stories.tsx +++ b/ts/components/OutgoingGiftBadgeModal.stories.tsx @@ -2,12 +2,10 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { text } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './OutgoingGiftBadgeModal'; import { OutgoingGiftBadgeModal } from './OutgoingGiftBadgeModal'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; import { BadgeCategory } from '../badges/BadgeCategory'; @@ -30,11 +28,8 @@ const getPreferredBadge = () => ({ }); const createProps = (overrideProps: Partial = {}): PropsType => ({ - recipientTitle: text( - 'recipientTitle', - overrideProps.recipientTitle || 'Default Name' - ), - badgeId: text('badgeId', overrideProps.badgeId || 'heart'), + recipientTitle: overrideProps.recipientTitle ?? 'Default Name', + badgeId: overrideProps.badgeId ?? 'heart', getPreferredBadge, hideOutgoingGiftBadgeModal: action('hideOutgoingGiftBadgeModal'), i18n, @@ -42,7 +37,9 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ export default { title: 'Components/OutgoingGiftBadgeModal', -}; + argTypes: {}, + args: {}, +} satisfies Meta; export function Normal(): JSX.Element { return ; @@ -56,7 +53,3 @@ export function MissingBadge(): JSX.Element { return ; } - -MissingBadge.story = { - name: 'Missing badge', -}; diff --git a/ts/components/PlaybackButton.stories.tsx b/ts/components/PlaybackButton.stories.tsx index 8080e83822..2ae8bffea4 100644 --- a/ts/components/PlaybackButton.stories.tsx +++ b/ts/components/PlaybackButton.stories.tsx @@ -4,12 +4,14 @@ import React from 'react'; import type { CSSProperties } from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { ButtonProps } from './PlaybackButton'; import { PlaybackButton } from './PlaybackButton'; export default { title: 'components/PlaybackButton', component: PlaybackButton, -}; +} satisfies Meta; const rowStyles: CSSProperties = { display: 'flex', diff --git a/ts/components/PlaybackButton.tsx b/ts/components/PlaybackButton.tsx index 0f97944088..c66ac08aa8 100644 --- a/ts/components/PlaybackButton.tsx +++ b/ts/components/PlaybackButton.tsx @@ -12,7 +12,7 @@ const SPRING_CONFIG = { velocity: 0.01, }; -type ButtonProps = { +export type ButtonProps = { context?: 'incoming' | 'outgoing'; variant: 'message' | 'mini' | 'draft'; mod: 'play' | 'pause' | 'download' | 'pending'; diff --git a/ts/components/PopperRootContext.tsx b/ts/components/PopperRootContext.tsx deleted file mode 100644 index 0bfa519af3..0000000000 --- a/ts/components/PopperRootContext.tsx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import * as React from 'react'; - -const makeApi = (classes?: Array) => ({ - createRoot: () => { - const div = document.createElement('div'); - - if (classes) { - classes.forEach(theme => { - div.classList.add(theme); - }); - } - - document.body.appendChild(div); - - return div; - }, - removeRoot: (root: HTMLElement) => { - document.body.removeChild(root); - }, -}); - -export const PopperRootContext = React.createContext(makeApi()); - -export type ClassyProviderProps = { - classes?: Array; - children?: React.ReactChildren; -}; - -export function ClassyProvider({ - classes, - children, -}: ClassyProviderProps): JSX.Element { - const api = React.useMemo(() => makeApi(classes), [classes]); - - return ( - - {children} - - ); -} diff --git a/ts/components/Preferences.stories.tsx b/ts/components/Preferences.stories.tsx index 88dcb62e5c..393b138116 100644 --- a/ts/components/Preferences.stories.tsx +++ b/ts/components/Preferences.stories.tsx @@ -1,17 +1,17 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; +import { action } from '@storybook/addon-actions'; import enMessages from '../../_locales/en/messages.json'; -import type { PropsDataType, PropsType } from './Preferences'; +import type { PropsType } from './Preferences'; import { Preferences } from './Preferences'; import { setupI18n } from '../util/setupI18n'; import { DEFAULT_CONVERSATION_COLOR } from '../types/Colors'; import { PhoneNumberSharingMode } from '../util/phoneNumberSharingMode'; import { PhoneNumberDiscoverability } from '../util/phoneNumberDiscoverability'; -import { objectMap } from '../util/objectMap'; import { DurationInSeconds } from '../util/durations'; const i18n = setupI18n('en', enMessages); @@ -44,145 +44,149 @@ const availableSpeakers = [ }, ]; -const getDefaultArgs = (): PropsDataType => ({ - availableCameras: [ - { - deviceId: - 'dfbe6effe70b0611ba0fdc2a9ea3f39f6cb110e6687948f7e5f016c111b7329c', - groupId: - '63ee218d2446869e40adfc958ff98263e51f74382b0143328ee4826f20a76f47', - kind: 'videoinput' as MediaDeviceKind, - label: 'FaceTime HD Camera (Built-in) (9fba:bced)', - }, - { - deviceId: - 'e2db196a31d50ff9b135299dc0beea67f65b1a25a06d8a4ce76976751bb7a08d', - groupId: - '218ba7f00d7b1239cca15b9116769e5e7d30cc01104ebf84d667643661e0ecf9', - kind: 'videoinput' as MediaDeviceKind, - label: 'Logitech Webcam (4e72:9058)', - }, - ], - availableMicrophones, - availableSpeakers, - blockedCount: 0, - customColors: {}, - defaultConversationColor: DEFAULT_CONVERSATION_COLOR, - deviceName: 'Work Windows ME', - hasAudioNotifications: true, - hasAutoDownloadUpdate: true, - hasAutoLaunch: true, - hasCallNotifications: true, - hasCallRingtoneNotification: false, - hasCountMutedConversations: false, - hasCustomTitleBar: true, - hasHideMenuBar: false, - hasIncomingCallNotifications: true, - hasLinkPreviews: true, - hasMediaCameraPermissions: true, - hasMediaPermissions: true, - hasMessageAudio: true, - hasMinimizeToAndStartInSystemTray: true, - hasMinimizeToSystemTray: true, - hasNotificationAttention: false, - hasNotifications: true, - hasReadReceipts: true, - hasRelayCalls: false, - hasSpellCheck: true, - hasStoriesDisabled: false, - hasTextFormatting: true, - hasTypingIndicators: true, - initialSpellCheckSetting: true, - isAutoDownloadUpdatesSupported: true, - isAutoLaunchSupported: true, - isFormattingFlagEnabled: true, - isHideMenuBarSupported: true, - isNotificationAttentionSupported: true, - isPhoneNumberSharingSupported: true, - isSyncSupported: true, - isSystemTraySupported: true, - isMinimizeToAndStartInSystemTraySupported: true, - lastSyncTime: Date.now(), - notificationContent: 'name', - selectedCamera: - 'dfbe6effe70b0611ba0fdc2a9ea3f39f6cb110e6687948f7e5f016c111b7329c', - selectedMicrophone: availableMicrophones[0], - selectedSpeaker: availableSpeakers[1], - shouldShowStoriesSettings: true, - sentMediaQualitySetting: 'standard', - themeSetting: 'system', - universalExpireTimer: DurationInSeconds.HOUR, - whoCanFindMe: PhoneNumberDiscoverability.Discoverable, - whoCanSeeMe: PhoneNumberSharingMode.Everybody, - zoomFactor: 1, -}); - -const defaultArgTypes: Record = {}; -objectMap(getDefaultArgs(), (key, defaultValue) => { - defaultArgTypes[key] = { defaultValue }; -}); - export default { title: 'Components/Preferences', component: Preferences, - argTypes: { - // ...defaultArgTypes, + args: { + i18n, - i18n: { - defaultValue: i18n, - }, + availableCameras: [ + { + deviceId: + 'dfbe6effe70b0611ba0fdc2a9ea3f39f6cb110e6687948f7e5f016c111b7329c', + groupId: + '63ee218d2446869e40adfc958ff98263e51f74382b0143328ee4826f20a76f47', + kind: 'videoinput' as MediaDeviceKind, + label: 'FaceTime HD Camera (Built-in) (9fba:bced)', + }, + { + deviceId: + 'e2db196a31d50ff9b135299dc0beea67f65b1a25a06d8a4ce76976751bb7a08d', + groupId: + '218ba7f00d7b1239cca15b9116769e5e7d30cc01104ebf84d667643661e0ecf9', + kind: 'videoinput' as MediaDeviceKind, + label: 'Logitech Webcam (4e72:9058)', + }, + ], + availableLocales: ['en'], + availableMicrophones, + availableSpeakers, + blockedCount: 0, + customColors: {}, + defaultConversationColor: DEFAULT_CONVERSATION_COLOR, + deviceName: 'Work Windows ME', + hasAudioNotifications: true, + hasAutoDownloadUpdate: true, + hasAutoLaunch: true, + hasCallNotifications: true, + hasCallRingtoneNotification: false, + hasCountMutedConversations: false, + hasCustomTitleBar: true, + hasHideMenuBar: false, + hasIncomingCallNotifications: true, + hasLinkPreviews: true, + hasMediaCameraPermissions: true, + hasMediaPermissions: true, + hasMessageAudio: true, + hasMinimizeToAndStartInSystemTray: true, + hasMinimizeToSystemTray: true, + hasNotificationAttention: false, + hasNotifications: true, + hasReadReceipts: true, + hasRelayCalls: false, + hasSpellCheck: true, + hasStoriesDisabled: false, + hasTextFormatting: true, + hasTypingIndicators: true, + initialSpellCheckSetting: true, + isAutoDownloadUpdatesSupported: true, + isAutoLaunchSupported: true, + isFormattingFlagEnabled: true, + isHideMenuBarSupported: true, + isNotificationAttentionSupported: true, + isPhoneNumberSharingSupported: true, + isSyncSupported: true, + isSystemTraySupported: true, + isMinimizeToAndStartInSystemTraySupported: true, + lastSyncTime: Date.now(), + localeOverride: null, + notificationContent: 'name', + preferredSystemLocales: ['en'], + resolvedLocale: 'en', + selectedCamera: + 'dfbe6effe70b0611ba0fdc2a9ea3f39f6cb110e6687948f7e5f016c111b7329c', + selectedMicrophone: availableMicrophones[0], + selectedSpeaker: availableSpeakers[1], + shouldShowStoriesSettings: true, + sentMediaQualitySetting: 'standard', + themeSetting: 'system', + universalExpireTimer: DurationInSeconds.HOUR, + whoCanFindMe: PhoneNumberDiscoverability.Discoverable, + whoCanSeeMe: PhoneNumberSharingMode.Everybody, + zoomFactor: 1, - addCustomColor: { action: true }, - closeSettings: { action: true }, - doDeleteAllData: { action: true }, - doneRendering: { action: true }, - editCustomColor: { action: true }, - executeMenuRole: { action: true }, - getConversationsWithCustomColor: { action: true }, - makeSyncRequest: { action: true }, - onAudioNotificationsChange: { action: true }, - onAutoDownloadUpdateChange: { action: true }, - onAutoLaunchChange: { action: true }, - onCallNotificationsChange: { action: true }, - onCallRingtoneNotificationChange: { action: true }, - onCountMutedConversationsChange: { action: true }, - onHasStoriesDisabledChanged: { action: true }, - onHideMenuBarChange: { action: true }, - onIncomingCallNotificationsChange: { action: true }, - onLastSyncTimeChange: { action: true }, - onMediaCameraPermissionsChange: { action: true }, - onMediaPermissionsChange: { action: true }, - onMessageAudioChange: { action: true }, - onMinimizeToAndStartInSystemTrayChange: { action: true }, - onMinimizeToSystemTrayChange: { action: true }, - onNotificationAttentionChange: { action: true }, - onNotificationContentChange: { action: true }, - onNotificationsChange: { action: true }, - onRelayCallsChange: { action: true }, - onSelectedCameraChange: { action: true }, - onSelectedMicrophoneChange: { action: true }, - onSelectedSpeakerChange: { action: true }, - onSentMediaQualityChange: { action: true }, - onSpellCheckChange: { action: true }, - onTextFormattingChange: { action: true }, - onThemeChange: { action: true }, - onUniversalExpireTimerChange: { action: true }, - onWhoCanSeeMeChange: { action: true }, - onWhoCanFindMeChange: { action: true }, - onZoomFactorChange: { action: true }, - removeCustomColor: { action: true }, - removeCustomColorOnConversations: { action: true }, - resetAllChatColors: { action: true }, - resetDefaultChatColor: { action: true }, - setGlobalDefaultConversationColor: { action: true }, - }, -} as Meta; + getConversationsWithCustomColor: () => Promise.resolve([]), + + addCustomColor: action('addCustomColor'), + closeSettings: action('closeSettings'), + doDeleteAllData: action('doDeleteAllData'), + doneRendering: action('doneRendering'), + editCustomColor: action('editCustomColor'), + executeMenuRole: action('executeMenuRole'), + makeSyncRequest: action('makeSyncRequest'), + onAudioNotificationsChange: action('onAudioNotificationsChange'), + onAutoDownloadUpdateChange: action('onAutoDownloadUpdateChange'), + onAutoLaunchChange: action('onAutoLaunchChange'), + onCallNotificationsChange: action('onCallNotificationsChange'), + onCallRingtoneNotificationChange: action( + 'onCallRingtoneNotificationChange' + ), + onCountMutedConversationsChange: action('onCountMutedConversationsChange'), + onHasStoriesDisabledChanged: action('onHasStoriesDisabledChanged'), + onHideMenuBarChange: action('onHideMenuBarChange'), + onIncomingCallNotificationsChange: action( + 'onIncomingCallNotificationsChange' + ), + onLocaleChange: action('onLocaleChange'), + onLastSyncTimeChange: action('onLastSyncTimeChange'), + onMediaCameraPermissionsChange: action('onMediaCameraPermissionsChange'), + onMediaPermissionsChange: action('onMediaPermissionsChange'), + onMessageAudioChange: action('onMessageAudioChange'), + onMinimizeToAndStartInSystemTrayChange: action( + 'onMinimizeToAndStartInSystemTrayChange' + ), + onMinimizeToSystemTrayChange: action('onMinimizeToSystemTrayChange'), + onNotificationAttentionChange: action('onNotificationAttentionChange'), + onNotificationContentChange: action('onNotificationContentChange'), + onNotificationsChange: action('onNotificationsChange'), + onRelayCallsChange: action('onRelayCallsChange'), + onSelectedCameraChange: action('onSelectedCameraChange'), + onSelectedMicrophoneChange: action('onSelectedMicrophoneChange'), + onSelectedSpeakerChange: action('onSelectedSpeakerChange'), + onSentMediaQualityChange: action('onSentMediaQualityChange'), + onSpellCheckChange: action('onSpellCheckChange'), + onTextFormattingChange: action('onTextFormattingChange'), + onThemeChange: action('onThemeChange'), + onUniversalExpireTimerChange: action('onUniversalExpireTimerChange'), + onWhoCanSeeMeChange: action('onWhoCanSeeMeChange'), + onWhoCanFindMeChange: action('onWhoCanFindMeChange'), + onZoomFactorChange: action('onZoomFactorChange'), + removeCustomColor: action('removeCustomColor'), + removeCustomColorOnConversations: action( + 'removeCustomColorOnConversations' + ), + resetAllChatColors: action('resetAllChatColors'), + resetDefaultChatColor: action('resetDefaultChatColor'), + setGlobalDefaultConversationColor: action( + 'setGlobalDefaultConversationColor' + ), + } satisfies PropsType, +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const _Preferences = Template.bind({}); -_Preferences.args = getDefaultArgs(); export const Blocked1 = Template.bind({}); Blocked1.args = { @@ -198,9 +202,6 @@ export const CustomUniversalExpireTimer = Template.bind({}); CustomUniversalExpireTimer.args = { universalExpireTimer: DurationInSeconds.fromSeconds(9000), }; -CustomUniversalExpireTimer.story = { - name: 'Custom universalExpireTimer', -}; export const PNPSharingDisabled = Template.bind({}); PNPSharingDisabled.args = { @@ -208,9 +209,6 @@ PNPSharingDisabled.args = { whoCanFindMe: PhoneNumberDiscoverability.Discoverable, isPhoneNumberSharingSupported: true, }; -PNPSharingDisabled.story = { - name: 'PNP Sharing Disabled', -}; export const PNPDiscoverabilityDisabled = Template.bind({}); PNPDiscoverabilityDisabled.args = { @@ -218,9 +216,6 @@ PNPDiscoverabilityDisabled.args = { whoCanFindMe: PhoneNumberDiscoverability.NotDiscoverable, isPhoneNumberSharingSupported: true, }; -PNPDiscoverabilityDisabled.story = { - name: 'PNP Discoverability Disabled', -}; export const FormattingDisabled = Template.bind({}); FormattingDisabled.args = { diff --git a/ts/components/Preferences.tsx b/ts/components/Preferences.tsx index 11918e9c87..68aff9c472 100644 --- a/ts/components/Preferences.tsx +++ b/ts/components/Preferences.tsx @@ -10,9 +10,10 @@ import React, { useRef, useState, } from 'react'; -import { noop } from 'lodash'; +import { noop, partition } from 'lodash'; import classNames from 'classnames'; import uuid from 'uuid'; +import * as LocaleMatcher from '@formatjs/intl-localematcher'; import type { MediaDeviceSettings } from '../types/Calling'; import type { @@ -59,6 +60,10 @@ import { useEscapeHandling } from '../hooks/useEscapeHandling'; import { useUniqueId } from '../hooks/useUniqueId'; import { useTheme } from '../hooks/useTheme'; import { focusableSelectors } from '../util/focusableSelectors'; +import { Modal } from './Modal'; +import { SearchInput } from './SearchInput'; +import { removeDiacritics } from '../util/removeDiacritics'; +import { assertDev } from '../util/assert'; type CheckboxChangeHandlerType = (value: boolean) => unknown; type SelectChangeHandlerType = (value: T) => unknown; @@ -103,6 +108,12 @@ export type PropsDataType = { whoCanSeeMe: PhoneNumberSharingMode; zoomFactor: ZoomFactorType; + // Localization + availableLocales: ReadonlyArray; + localeOverride: string | null; + preferredSystemLocales: ReadonlyArray; + resolvedLocale: string; + // Other props hasCustomTitleBar: boolean; initialSpellCheckSetting: boolean; @@ -161,6 +172,7 @@ type PropsFunctionType = { onHideMenuBarChange: CheckboxChangeHandlerType; onIncomingCallNotificationsChange: CheckboxChangeHandlerType; onLastSyncTimeChange: (time: number) => unknown; + onLocaleChange: (locale: string | null) => void; onMediaCameraPermissionsChange: CheckboxChangeHandlerType; onMediaPermissionsChange: CheckboxChangeHandlerType; onMessageAudioChange: CheckboxChangeHandlerType; @@ -204,6 +216,11 @@ enum Page { PNP = 'PNP', } +enum LanguageDialog { + Selection, + Confirmation, +} + const DEFAULT_ZOOM_FACTORS = [ { text: '75%', @@ -230,6 +247,7 @@ const DEFAULT_ZOOM_FACTORS = [ export function Preferences({ addCustomColor, availableCameras, + availableLocales, availableMicrophones, availableSpeakers, blockedCount, @@ -289,6 +307,7 @@ export function Preferences({ onHideMenuBarChange, onIncomingCallNotificationsChange, onLastSyncTimeChange, + onLocaleChange, onMediaCameraPermissionsChange, onMediaPermissionsChange, onMessageAudioChange, @@ -309,16 +328,19 @@ export function Preferences({ onWhoCanSeeMeChange, onWhoCanFindMeChange, onZoomFactorChange, + preferredSystemLocales, removeCustomColor, removeCustomColorOnConversations, resetAllChatColors, resetDefaultChatColor, + resolvedLocale, selectedCamera, selectedMicrophone, selectedSpeaker, sentMediaQualitySetting, setGlobalDefaultConversationColor, shouldShowStoriesSettings, + localeOverride, themeSetting, universalExpireTimer = DurationInSeconds.ZERO, whoCanFindMe, @@ -328,6 +350,7 @@ export function Preferences({ const storiesId = useUniqueId(); const themeSelectId = useUniqueId(); const zoomSelectId = useUniqueId(); + const languageId = useUniqueId(); const [confirmDelete, setConfirmDelete] = useState(false); const [confirmStoriesOff, setConfirmStoriesOff] = useState(false); @@ -336,13 +359,31 @@ export function Preferences({ const [nowSyncing, setNowSyncing] = useState(false); const [showDisappearingTimerDialog, setShowDisappearingTimerDialog] = useState(false); + const [languageDialog, setLanguageDialog] = useState( + null + ); + const [selectedLanguageLocale, setSelectedLanguageLocale] = useState< + string | null + >(localeOverride); + const [languageSearchInput, setLanguageSearchInput] = useState(''); const theme = useTheme(); + function closeLanguageDialog() { + setLanguageDialog(null); + setSelectedLanguageLocale(localeOverride); + } + useEffect(() => { doneRendering(); }, [doneRendering]); - useEscapeHandling(closeSettings); + useEscapeHandling(() => { + if (languageDialog != null) { + closeLanguageDialog(); + } else { + closeSettings(); + } + }); const onZoomSelectChange = useCallback( (value: string) => { @@ -395,6 +436,95 @@ export function Preferences({ [onSelectedSpeakerChange, availableSpeakers] ); + const localeDisplayNames = window.SignalContext.getLocaleDisplayNames(); + + const getLocaleDisplayName = useCallback( + (inLocale: string, ofLocale: string): string => { + const displayName = localeDisplayNames[inLocale]?.[ofLocale]; + assertDev( + displayName != null, + `Locale display name in ${inLocale} of ${ofLocale} does not exist` + ); + return ( + displayName ?? + new Intl.DisplayNames(inLocale, { + type: 'language', + languageDisplay: 'standard', + style: 'long', + fallback: 'code', + }).of(ofLocale) + ); + }, + [localeDisplayNames] + ); + + const localeSearchOptions = useMemo(() => { + const collator = new Intl.Collator('en', { usage: 'sort' }); + + const availableLocalesOptions = availableLocales + .map(locale => { + const currentLocaleLabel = getLocaleDisplayName(resolvedLocale, locale); + const matchingLocaleLabel = getLocaleDisplayName(locale, locale); + return { locale, currentLocaleLabel, matchingLocaleLabel }; + }) + .sort((a, b) => { + return collator.compare(a.locale, b.locale); + }); + + const [localeOverrideMatches, localeOverrideNonMatches] = partition( + availableLocalesOptions, + option => { + return option.locale === localeOverride; + } + ); + + const preferredSystemLocaleMatch = LocaleMatcher.match( + preferredSystemLocales as Array, // bad types + availableLocales as Array, // bad types + 'en', + { algorithm: 'best fit' } + ); + + return [ + ...localeOverrideMatches, + { + locale: null, + currentLocaleLabel: i18n('icu:Preferences__Language__SystemLanguage'), + matchingLocaleLabel: getLocaleDisplayName( + preferredSystemLocaleMatch, + preferredSystemLocaleMatch + ), + }, + ...localeOverrideNonMatches, + ]; + }, [ + i18n, + availableLocales, + resolvedLocale, + localeOverride, + preferredSystemLocales, + getLocaleDisplayName, + ]); + + const localeSearchResults = useMemo(() => { + return localeSearchOptions.filter(option => { + const input = removeDiacritics(languageSearchInput.trim().toLowerCase()); + + if (input === '') { + return true; + } + + function isMatch(value: string) { + return removeDiacritics(value.toLowerCase()).includes(input); + } + + return ( + isMatch(option.currentLocaleLabel) || + (option.matchingLocaleLabel && isMatch(option.matchingLocaleLabel)) + ); + }); + }, [localeSearchOptions, languageSearchInput]); + let settings: JSX.Element | undefined; if (page === Page.General) { settings = ( @@ -504,6 +634,129 @@ export function Preferences({
+ {localeOverride != null + ? getLocaleDisplayName(resolvedLocale, localeOverride) + : i18n('icu:Preferences__Language__SystemLanguage')} + + } + onClick={() => { + setLanguageDialog(LanguageDialog.Selection); + }} + /> + {languageDialog === LanguageDialog.Selection && ( + { + setLanguageSearchInput(event.currentTarget.value); + }} + /> + } + modalFooter={ + <> + + + + } + > + {localeSearchResults.length === 0 && ( +
+ {i18n('icu:Preferences__Language__NoResults', { + searchTerm: languageSearchInput.trim(), + })} +
+ )} + {localeSearchResults.map(option => { + const id = `${languageId}:${option.locale ?? 'system'}`; + const isSelected = option.locale === selectedLanguageLocale; + return ( + + ); + })} +
+ )} + {languageDialog === LanguageDialog.Confirmation && ( + { + onLocaleChange(selectedLanguageLocale); + }, + }, + ]} + > + {i18n('icu:Preferences__LanguageModal__Restart__Description')} + + )} + {i18n('icu:Preferences--theme')} @@ -532,6 +785,7 @@ export function Preferences({ } /> { setPage(Page.ChatColor); @@ -548,6 +802,7 @@ export function Preferences({ } /> {i18n('icu:Preferences--zoom')} @@ -1307,6 +1562,7 @@ export function Preferences({ > {i18n('icu:Preferences__button--notifications')} +
- {distributionId && removeFromStory && uuid ? ( + {distributionId && removeFromStory && serviceId ? ( removeFromStory(distributionId, [uuid])} + removeFromStory={() => removeFromStory(distributionId, [serviceId])} verifyContact={() => setSelectedContact(contact)} /> ) : ( diff --git a/ts/components/SafetyNumberModal.tsx b/ts/components/SafetyNumberModal.tsx index 7411798809..17fc3e8cab 100644 --- a/ts/components/SafetyNumberModal.tsx +++ b/ts/components/SafetyNumberModal.tsx @@ -1,53 +1,29 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { useState, useCallback } from 'react'; +import React from 'react'; -import { SafetyNumberMode } from '../types/safetyNumber'; import { isSafetyNumberNotAvailable } from '../util/isSafetyNumberNotAvailable'; import { Modal } from './Modal'; import type { PropsType as SafetyNumberViewerPropsType } from './SafetyNumberViewer'; import { SafetyNumberViewer } from './SafetyNumberViewer'; -import { SafetyNumberOnboarding } from './SafetyNumberOnboarding'; import { SafetyNumberNotReady } from './SafetyNumberNotReady'; type PropsType = { toggleSafetyNumberModal: () => unknown; - hasCompletedSafetyNumberOnboarding: boolean; - markHasCompletedSafetyNumberOnboarding: () => unknown; } & Omit; export function SafetyNumberModal({ i18n, toggleSafetyNumberModal, - hasCompletedSafetyNumberOnboarding, - markHasCompletedSafetyNumberOnboarding, ...safetyNumberViewerProps }: PropsType): JSX.Element | null { - const { contact, safetyNumberMode } = safetyNumberViewerProps; - - const [isOnboarding, setIsOnboarding] = useState( - safetyNumberMode !== SafetyNumberMode.JustE164 && - !hasCompletedSafetyNumberOnboarding - ); - - const showOnboarding = useCallback(() => { - setIsOnboarding(true); - }, [setIsOnboarding]); - - const hideOnboarding = useCallback(() => { - setIsOnboarding(false); - markHasCompletedSafetyNumberOnboarding(); - }, [setIsOnboarding, markHasCompletedSafetyNumberOnboarding]); - - const missingRequiredE164 = - safetyNumberMode !== SafetyNumberMode.DefaultACIAndMaybeE164 && - !contact.e164; + const { contact } = safetyNumberViewerProps; let title: string | undefined; let content: JSX.Element; let hasXButton = true; - if (missingRequiredE164 || isSafetyNumberNotAvailable(contact)) { + if (isSafetyNumberNotAvailable(contact)) { content = ( ); hasXButton = false; - } else if (isOnboarding) { - content = ; } else { title = i18n('icu:SafetyNumberModal__title'); @@ -64,7 +38,6 @@ export function SafetyNumberModal({ ); diff --git a/ts/components/SafetyNumberNotReady.stories.tsx b/ts/components/SafetyNumberNotReady.stories.tsx index 108d1c0b7d..dc3f3e51b5 100644 --- a/ts/components/SafetyNumberNotReady.stories.tsx +++ b/ts/components/SafetyNumberNotReady.stories.tsx @@ -3,7 +3,8 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './SafetyNumberNotReady'; import { SafetyNumberNotReady } from './SafetyNumberNotReady'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -12,12 +13,8 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/SafetyNumberNotReady', -}; +} satisfies Meta; export function Default(): JSX.Element { return ; } - -Default.story = { - name: 'Safety Number Not Ready', -}; diff --git a/ts/components/SafetyNumberNotReady.tsx b/ts/components/SafetyNumberNotReady.tsx index 5b15caf3b1..5558520e69 100644 --- a/ts/components/SafetyNumberNotReady.tsx +++ b/ts/components/SafetyNumberNotReady.tsx @@ -8,7 +8,7 @@ import { Modal } from './Modal'; import { Intl } from './Intl'; import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser'; import type { LocalizerType } from '../types/Util'; -import { SAFETY_NUMBER_MIGRATION_URL } from '../types/support'; +import { SAFETY_NUMBER_URL } from '../types/support'; export type PropsType = { i18n: LocalizerType; @@ -16,7 +16,7 @@ export type PropsType = { }; function onLearnMore() { - openLinkInWebBrowser(SAFETY_NUMBER_MIGRATION_URL); + openLinkInWebBrowser(SAFETY_NUMBER_URL); } export function SafetyNumberNotReady({ diff --git a/ts/components/SafetyNumberOnboarding.stories.tsx b/ts/components/SafetyNumberOnboarding.stories.tsx deleted file mode 100644 index fd062bf0ab..0000000000 --- a/ts/components/SafetyNumberOnboarding.stories.tsx +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2023 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import * as React from 'react'; -import { action } from '@storybook/addon-actions'; - -import { SafetyNumberOnboarding } from './SafetyNumberOnboarding'; -import { setupI18n } from '../util/setupI18n'; -import enMessages from '../../_locales/en/messages.json'; - -const i18n = setupI18n('en', enMessages); - -export default { - title: 'Components/SafetyNumberOnboarding', -}; - -export function Default(): JSX.Element { - return ; -} - -Default.story = { - name: 'Safety Number Onboarding', -}; diff --git a/ts/components/SafetyNumberOnboarding.tsx b/ts/components/SafetyNumberOnboarding.tsx deleted file mode 100644 index fe7bd4329e..0000000000 --- a/ts/components/SafetyNumberOnboarding.tsx +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2023 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React, { useCallback, useRef } from 'react'; -import Lottie from 'lottie-react'; -import type { LottieRefCurrentProps } from 'lottie-react'; - -import { Button, ButtonVariant } from './Button'; -import { Intl } from './Intl'; -import type { LocalizerType } from '../types/Util'; -import { SAFETY_NUMBER_MIGRATION_URL } from '../types/support'; -import { useReducedMotion } from '../hooks/useReducedMotion'; -import animationData from '../../images/safety-number-onboarding.json'; -import reducedAnimationData from '../../images/safety-number-onboarding-reduced-motion.json'; - -export type PropsType = { - i18n: LocalizerType; - onClose: () => void; -}; - -export function SafetyNumberOnboarding({ - i18n, - onClose, -}: PropsType): JSX.Element | null { - const isMotionReduced = useReducedMotion(); - const lottieRef = useRef(null); - - const onDOMLoaded = useCallback(() => { - if (isMotionReduced) { - lottieRef.current?.goToAndPlay(0); - return; - } - - lottieRef.current?.playSegments( - [ - [0, 360], - [60, 360], - ], - true - ); - }, [isMotionReduced]); - - return ( -
-

- -

-

- -

-

- -

- -
- - - -
- -
- ); -} diff --git a/ts/components/SafetyNumberViewer.stories.tsx b/ts/components/SafetyNumberViewer.stories.tsx index eb4766466e..258691e75f 100644 --- a/ts/components/SafetyNumberViewer.stories.tsx +++ b/ts/components/SafetyNumberViewer.stories.tsx @@ -3,15 +3,10 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; -import { boolean, text } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './SafetyNumberViewer'; import { SafetyNumberViewer } from './SafetyNumberViewer'; import { setupI18n } from '../util/setupI18n'; -import { - SafetyNumberIdentifierType, - SafetyNumberMode, -} from '../types/safetyNumber'; import enMessages from '../../_locales/en/messages.json'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; @@ -73,86 +68,29 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ contact: overrideProps.contact || contactWithAllData, generateSafetyNumber: action('generate-safety-number'), i18n, - safetyNumberMode: - overrideProps.safetyNumberMode ?? SafetyNumberMode.DefaultE164AndThenACI, - safetyNumbers: overrideProps.safetyNumbers ?? [ - { - identifierType: SafetyNumberIdentifierType.ACIIdentifier, - numberBlocks: text( - 'safetyNumber', - generateNumberBlocks().join(' ') - ).split(' '), - qrData: generateQRData(), - }, - ], + safetyNumber: + 'safetyNumber' in overrideProps + ? overrideProps.safetyNumber + : { + numberBlocks: generateNumberBlocks(), + qrData: generateQRData(), + }, toggleVerified: action('toggle-verified'), - verificationDisabled: boolean( - 'verificationDisabled', + verificationDisabled: overrideProps.verificationDisabled !== undefined ? overrideProps.verificationDisabled - : false - ), + : false, onClose: action('onClose'), }); export default { title: 'Components/SafetyNumberViewer', -}; +} satisfies Meta; export function SafetyNumber(): JSX.Element { return ; } -export function SafetyNumberBeforeE164Transition(): JSX.Element { - return ( - - ); -} - -SafetyNumberBeforeE164Transition.story = { - name: 'Safety Number (before e164 transition)', -}; - -export function SafetyNumberE164Transition(): JSX.Element { - return ( - - ); -} - -SafetyNumberE164Transition.story = { - name: 'Safety Number (e164 transition)', -}; - export function SafetyNumberNotVerified(): JSX.Element { return ( ); } - -NoPhoneNumberCannotVerify.story = { - name: 'No Phone Number (cannot verify)', -}; diff --git a/ts/components/SafetyNumberViewer.tsx b/ts/components/SafetyNumberViewer.tsx index 6a54006327..03f8b31985 100644 --- a/ts/components/SafetyNumberViewer.tsx +++ b/ts/components/SafetyNumberViewer.tsx @@ -1,8 +1,7 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { useState } from 'react'; -import classNames from 'classnames'; +import React from 'react'; import { Button, ButtonVariant } from './Button'; import { QrCode } from './QrCode'; @@ -11,21 +10,15 @@ import { Intl } from './Intl'; import { Emojify } from './conversation/Emojify'; import type { LocalizerType } from '../types/Util'; import type { SafetyNumberType } from '../types/safetyNumber'; -import { SAFETY_NUMBER_MIGRATION_URL } from '../types/support'; -import { - SafetyNumberIdentifierType, - SafetyNumberMode, -} from '../types/safetyNumber'; +import { SAFETY_NUMBER_URL } from '../types/support'; export type PropsType = { contact: ConversationType; generateSafetyNumber: (contact: ConversationType) => void; i18n: LocalizerType; onClose: () => void; - safetyNumberMode: SafetyNumberMode; - safetyNumbers?: ReadonlyArray; + safetyNumber?: SafetyNumberType; toggleVerified: (contact: ConversationType) => void; - showOnboarding?: () => void; verificationDisabled: boolean; }; @@ -34,13 +27,10 @@ export function SafetyNumberViewer({ generateSafetyNumber, i18n, onClose, - safetyNumberMode, - safetyNumbers, + safetyNumber, toggleVerified, - showOnboarding, verificationDisabled, }: PropsType): JSX.Element | null { - const hasSafetyNumbers = safetyNumbers != null; React.useEffect(() => { if (!contact) { return; @@ -49,13 +39,13 @@ export function SafetyNumberViewer({ generateSafetyNumber(contact); }, [contact, generateSafetyNumber]); - const [selectedIndex, setSelectedIndex] = useState(0); + // Keyboard navigation - if (!contact || !hasSafetyNumbers) { + if (!contact) { return null; } - if (!safetyNumbers.length) { + if (!safetyNumber) { return (
{i18n('icu:cannotGenerateSafetyNumber')}
@@ -83,133 +73,36 @@ export function SafetyNumberViewer({ ? i18n('icu:SafetyNumberViewer__clearVerification') : i18n('icu:SafetyNumberViewer__markAsVerified'); - const isMigrationVisible = safetyNumberMode !== SafetyNumberMode.JustE164; - - const visibleSafetyNumber = safetyNumbers.at(selectedIndex); - if (!visibleSafetyNumber) { - return null; - } - - const cardClassName = classNames('module-SafetyNumberViewer__card', { - 'module-SafetyNumberViewer__card--aci': - visibleSafetyNumber.identifierType === - SafetyNumberIdentifierType.ACIIdentifier, - 'module-SafetyNumberViewer__card--e164': - visibleSafetyNumber.identifierType === - SafetyNumberIdentifierType.E164Identifier, - }); - - const numberBlocks = visibleSafetyNumber.numberBlocks.join(' '); + const numberBlocks = safetyNumber.numberBlocks.join(' '); const safetyNumberCard = (
-
+
{numberBlocks}
- - {selectedIndex > 0 && ( -
); - const carousel = ( -
- {safetyNumbers.map(({ identifierType }, index) => { - return ( -
- ); - return (
- {isMigrationVisible && ( -
- - )} - {safetyNumberCard} - {safetyNumbers.length > 1 && carousel} -
- {isMigrationVisible ? ( - - ) : ( - - )} +
- - + +
diff --git a/ts/components/Select.stories.tsx b/ts/components/Select.stories.tsx index 82b938b15b..d137fdd715 100644 --- a/ts/components/Select.stories.tsx +++ b/ts/components/Select.stories.tsx @@ -3,12 +3,13 @@ import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { PropsType } from './Select'; import { Select } from './Select'; export default { title: 'Components/Select', -}; +} satisfies Meta; export function Normal(): JSX.Element { const [value, setValue] = useState(0); @@ -45,7 +46,3 @@ export function WithDisabledOptions(): JSX.Element { /> ); } - -WithDisabledOptions.story = { - name: 'With disabled options', -}; diff --git a/ts/components/SendEditWarningModal.tsx b/ts/components/SendEditWarningModal.tsx index e73d39db32..f0379db72d 100644 --- a/ts/components/SendEditWarningModal.tsx +++ b/ts/components/SendEditWarningModal.tsx @@ -30,9 +30,9 @@ export function SendEditWarningModal({ i18n={i18n} onCancel={onCancel} onClose={onCancel} - title={i18n('icu:SendEdit--dialog--title')} + title={i18n('icu:SendEdit--dialog--title2')} > - {i18n('icu:SendEdit--dialog--body')} + {i18n('icu:SendEdit--dialog--body2')} ); } diff --git a/ts/components/SendStoryModal.stories.tsx b/ts/components/SendStoryModal.stories.tsx index dd87801a79..4d9a4f0dfc 100644 --- a/ts/components/SendStoryModal.stories.tsx +++ b/ts/components/SendStoryModal.stories.tsx @@ -1,9 +1,10 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta } from '@storybook/react'; import React from 'react'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './SendStoryModal'; import enMessages from '../../_locales/en/messages.json'; import { SendStoryModal } from './SendStoryModal'; @@ -17,6 +18,7 @@ import { getFakeDistributionListsWithMembers, } from '../test-both/helpers/getFakeDistributionLists'; import { VIDEO_MP4 } from '../types/MIME'; +import type { StoryDistributionIdString } from '../types/StoryDistributionId'; const i18n = setupI18n('en', enMessages); @@ -28,99 +30,104 @@ const myStories = { export default { title: 'Components/SendStoryModal', component: SendStoryModal, - argTypes: { + args: { draftAttachment: { - defaultValue: { - contentType: VIDEO_MP4, - fileName: 'pixabay-Soap-Bubble-7141.mp4', - url: '/fixtures/pixabay-Soap-Bubble-7141.mp4', - }, + contentType: VIDEO_MP4, + fileName: 'pixabay-Soap-Bubble-7141.mp4', + url: '/fixtures/pixabay-Soap-Bubble-7141.mp4', + size: 1, }, - candidateConversations: { - defaultValue: Array.from(Array(100), () => getDefaultConversation()), - }, - distributionLists: { - defaultValue: [myStories], - }, - getPreferredBadge: { action: true }, - groupConversations: { - defaultValue: Array.from(Array(7), getDefaultGroup), - }, - groupStories: { - defaultValue: Array.from(Array(2), getDefaultGroup), - }, - hasFirstStoryPostExperience: { - defaultValue: false, - }, - i18n: { - defaultValue: i18n, - }, - me: { - defaultValue: getDefaultConversation(), - }, - onClose: { action: true }, - onDeleteList: { action: true }, - onDistributionListCreated: { action: true }, - onHideMyStoriesFrom: { action: true }, - onMediaPlaybackStart: { action: true }, - onSend: { action: true }, - onViewersUpdated: { action: true }, - setMyStoriesToAllSignalConnections: { action: true }, - mostRecentActiveStoryTimestampByGroupOrDistributionList: { - defaultValue: {}, - }, - signalConnections: { - defaultValue: Array.from(Array(42), getDefaultConversation), - }, - toggleGroupsForStorySend: { action: true }, - toggleSignalConnectionsModal: { action: true }, + candidateConversations: Array.from(Array(100), () => + getDefaultConversation() + ), + distributionLists: [myStories], + getPreferredBadge: () => undefined, + groupConversations: Array.from(Array(7), getDefaultGroup), + groupStories: Array.from(Array(2), getDefaultGroup), + hasFirstStoryPostExperience: false, + i18n, + me: getDefaultConversation(), + onClose: action('onClose'), + onDeleteList: action('onDeleteList'), + onDistributionListCreated: () => + Promise.resolve('' as StoryDistributionIdString), + onHideMyStoriesFrom: action('onHideMyStoriesFrom'), + onMediaPlaybackStart: action('onMediaPlaybackStart'), + onSend: action('onSend'), + onViewersUpdated: action('onViewersUpdated'), + setMyStoriesToAllSignalConnections: action( + 'setMyStoriesToAllSignalConnections' + ), + mostRecentActiveStoryTimestampByGroupOrDistributionList: {}, + signalConnections: Array.from(Array(42), getDefaultConversation), + toggleGroupsForStorySend: () => Promise.resolve(), + toggleSignalConnectionsModal: action('toggleSignalConnectionsModal'), }, -} as Meta; +} satisfies Meta; -// eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +export function Modal(args: PropsType): JSX.Element { + return ( + + ); +} -export const Modal = Template.bind({}); -Modal.args = { - distributionLists: getFakeDistributionListsWithMembers(), -}; +export function BlockList(args: PropsType): JSX.Element { + return ( + + ); +} -export const BlockList = Template.bind({}); -BlockList.args = { - distributionLists: [ - { ...getMyStories(), members: [getDefaultConversation()] }, - ], - groupStories: [], -}; +export function AllowList(args: PropsType): JSX.Element { + return ( + + ); +} -export const AllowList = Template.bind({}); -AllowList.args = { - distributionLists: [ - { - ...getMyStories(), - isBlockList: false, - members: [getDefaultConversation()], - }, - ], - groupStories: [], -}; +export function FirstTime(args: PropsType): JSX.Element { + return ( + + ); +} -export const FirstTime = Template.bind({}); -FirstTime.args = { - distributionLists: [myStories], - groupStories: [], - hasFirstStoryPostExperience: true, -}; - -export const FirstTimeAlreadyConfiguredOnMobile = Template.bind({}); -FirstTime.args = { - distributionLists: [ - { - ...myStories, - isBlockList: false, - members: Array.from(Array(3), getDefaultConversation), - }, - ], - groupStories: [], - hasFirstStoryPostExperience: true, -}; +export function FirstTimeAlreadyConfiguredOnMobile( + args: PropsType +): JSX.Element { + return ( + + ); +} diff --git a/ts/components/SendStoryModal.tsx b/ts/components/SendStoryModal.tsx index bc32b64992..4ca4fbcaa4 100644 --- a/ts/components/SendStoryModal.tsx +++ b/ts/components/SendStoryModal.tsx @@ -10,6 +10,7 @@ import { filterAndSortConversationsByRecent } from '../util/filterAndSortConvers import type { ConversationType } from '../state/ducks/conversations'; import type { ConversationWithStoriesType } from '../state/selectors/conversations'; import type { LocalizerType } from '../types/Util'; +import { ThemeType } from '../types/Util'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { PropsType as StoriesSettingsModalPropsType } from './StoriesSettingsModal'; import { @@ -21,7 +22,8 @@ import { Page as StoriesSettingsPage, } from './StoriesSettingsModal'; import type { StoryDistributionListWithMembersDataType } from '../types/Stories'; -import type { UUIDStringType } from '../types/UUID'; +import type { StoryDistributionIdString } from '../types/StoryDistributionId'; +import type { ServiceIdString } from '../types/ServiceId'; import { Alert } from './Alert'; import { Avatar, AvatarSize } from './Avatar'; import { Button, ButtonSize, ButtonVariant } from './Button'; @@ -33,7 +35,6 @@ import { MY_STORY_ID, getStoryDistributionListName } from '../types/Stories'; import type { RenderModalPage, ModalPropsType } from './Modal'; import { PagedModal, ModalPage } from './Modal'; import { StoryDistributionListName } from './StoryDistributionListName'; -import { Theme } from '../util/theme'; import { isNotNil } from '../util/isNotNil'; import { StoryImage } from './StoryImage'; import type { AttachmentType } from '../types/Attachment'; @@ -41,6 +42,7 @@ import { useConfirmDiscard } from '../hooks/useConfirmDiscard'; import { getStoryBackground } from '../util/getStoryBackground'; import { makeObjectUrl, revokeObjectUrl } from '../types/VisualAttachment'; import { UserText } from './UserText'; +import { Theme } from '../util/theme'; export type PropsType = { draftAttachment: AttachmentType; @@ -54,21 +56,22 @@ export type PropsType = { i18n: LocalizerType; me: ConversationType; onClose: () => unknown; - onDeleteList: (listId: string) => unknown; + onDeleteList: (listId: StoryDistributionIdString) => unknown; onDistributionListCreated: ( name: string, - viewerUuids: Array - ) => Promise; + viewerServiceIds: Array + ) => Promise; onSelectedStoryList: (options: { conversationId: string; - distributionId: string | undefined; - uuids: Array; + distributionId: StoryDistributionIdString | undefined; + serviceIds: Array; }) => unknown; onSend: ( - listIds: Array, + listIds: Array, conversationIds: Array ) => unknown; signalConnections: Array; + theme: ThemeType; toggleGroupsForStorySend: (cids: Array) => Promise; mostRecentActiveStoryTimestampByGroupOrDistributionList: Record< string, @@ -99,21 +102,23 @@ const Page = { type PageType = SendStoryPage | StoriesSettingsPage; -function getListMemberUuids( +function getListMemberServiceIds( list: StoryDistributionListWithMembersDataType, signalConnections: Array -): Array { - const memberUuids = list.members.map(({ uuid }) => uuid).filter(isNotNil); +): Array { + const memberServiceIds = list.members + .map(({ serviceId }) => serviceId) + .filter(isNotNil); if (list.id === MY_STORY_ID && list.isBlockList) { - const excludeUuids = new Set(memberUuids); + const excludeServiceIds = new Set(memberServiceIds); return signalConnections - .map(conversation => conversation.uuid) + .map(conversation => conversation.serviceId) .filter(isNotNil) - .filter(uuid => !excludeUuids.has(uuid)); + .filter(serviceId => !excludeServiceIds.has(serviceId)); } - return memberUuids; + return memberServiceIds; } export function SendStoryModal({ @@ -138,6 +143,7 @@ export function SendStoryModal({ onViewersUpdated, setMyStoriesToAllSignalConnections, signalConnections, + theme, toggleGroupsForStorySend, mostRecentActiveStoryTimestampByGroupOrDistributionList, toggleSignalConnectionsModal, @@ -147,9 +153,9 @@ export function SendStoryModal({ const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard(i18n); - const [selectedListIds, setSelectedListIds] = useState>( - new Set() - ); + const [selectedListIds, setSelectedListIds] = useState< + Set + >(new Set()); const [selectedGroupIds, setSelectedGroupIds] = useState>( new Set() ); @@ -157,13 +163,13 @@ export function SendStoryModal({ () => distributionLists .filter(list => selectedListIds.has(list.id)) - .map(list => list.name) + .map(list => getStoryDistributionListName(i18n, list.id, list.name)) .concat( groupStories .filter(group => selectedGroupIds.has(group.id)) .map(group => group.title) ), - [distributionLists, groupStories, selectedGroupIds, selectedListIds] + [distributionLists, groupStories, selectedGroupIds, selectedListIds, i18n] ); const [searchTerm, setSearchTerm] = useState(''); @@ -215,7 +221,7 @@ export function SendStoryModal({ string | undefined >(); const [confirmDeleteList, setConfirmDeleteList] = useState< - { id: string; name: string } | undefined + { id: StoryDistributionIdString; name: string } | undefined >(); const [listIdToEdit, setListIdToEdit] = useState(); @@ -236,7 +242,7 @@ export function SendStoryModal({ return distributionLists.find(list => list.id === listIdToEdit); }, [distributionLists, listIdToEdit]); - // myStoriesPrivacy, myStoriesPrivacyUuids, and myStories are only used + // myStoriesPrivacy, myStoriesPrivacyServiceIds, and myStories are only used // during the first time posting to My Stories experience where we have // to select the privacy settings. const ogMyStories = useMemo( @@ -262,9 +268,7 @@ export function SendStoryModal({ if (page === Page.ChooseGroups) { selectedNames = chosenGroupNames.join(', '); } else { - selectedNames = selectedStoryNames - .map(listName => getStoryDistributionListName(i18n, listName, listName)) - .join(', '); + selectedNames = selectedStoryNames.join(', '); } const [objectUrl, setObjectUrl] = useState(undefined); @@ -304,18 +308,18 @@ export function SendStoryModal({
- {i18n('icu:stories')} - setPage(Page.ChooseViewers), - }, - { - label: i18n('icu:SendStoryModal__new-group--title'), - description: i18n('icu:SendStoryModal__new-group--description'), - icon: 'SendStoryModal__icon--group', - onClick: () => setPage(Page.ChooseGroups), - }, - ]} - moduleClassName="SendStoryModal__new-story" - popperOptions={{ - placement: 'bottom', - strategy: 'absolute', - }} - theme={Theme.Dark} - > - {({ openMenu, onKeyDown, ref, menuNode }) => ( -
- - {menuNode} -
- )} -
+
+ {i18n('icu:stories')} +
+
+ setPage(Page.ChooseViewers), + }, + { + label: i18n('icu:SendStoryModal__new-group--title'), + description: i18n( + 'icu:SendStoryModal__new-group--description' + ), + icon: 'SendStoryModal__icon--group', + onClick: () => setPage(Page.ChooseGroups), + }, + ]} + moduleClassName="SendStoryModal__new-story" + popperOptions={{ + placement: 'bottom', + strategy: 'absolute', + }} + theme={theme === ThemeType.dark ? Theme.Dark : Theme.Light} + > + {({ openMenu, onKeyDown, ref, menuNode }) => ( +
+ + {menuNode} +
+ )} +
+
{fullList.map(listOrGroup => // only group has a type field @@ -944,7 +956,7 @@ export function SendStoryModal({ {!confirmDiscardModal && ( confirmDiscardIf(selectedContacts.length > 0, onClose)} > {modal} @@ -955,7 +967,7 @@ export function SendStoryModal({ body={i18n('icu:SendStoryModal__announcements-only')} i18n={i18n} onClose={() => setHasAnnouncementsOnlyAlert(false)} - theme={Theme.Dark} + theme={theme === ThemeType.dark ? Theme.Dark : Theme.Light} /> )} {confirmRemoveGroupId && ( @@ -975,7 +987,7 @@ export function SendStoryModal({ onClose={() => { setConfirmRemoveGroupId(undefined); }} - theme={Theme.Dark} + theme={theme === ThemeType.dark ? Theme.Dark : Theme.Light} > {i18n('icu:SendStoryModal__confirm-remove-group')} @@ -997,7 +1009,7 @@ export function SendStoryModal({ onClose={() => { setConfirmDeleteList(undefined); }} - theme={Theme.Dark} + theme={theme === ThemeType.dark ? Theme.Dark : Theme.Light} > {i18n('icu:StoriesSettings__delete-list--confirm', { name: confirmDeleteList.name, diff --git a/ts/components/ShortcutGuide.stories.tsx b/ts/components/ShortcutGuide.stories.tsx index 6766b930b1..7520b62d31 100644 --- a/ts/components/ShortcutGuide.stories.tsx +++ b/ts/components/ShortcutGuide.stories.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; import type { Props } from './ShortcutGuide'; @@ -13,7 +13,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/ShortcutGuide', -}; +} satisfies Meta; const createProps = (overrideProps: Partial = {}): Props => ({ i18n, diff --git a/ts/components/SignalConnectionsModal.stories.tsx b/ts/components/SignalConnectionsModal.stories.tsx index dec509bb5d..8060316221 100644 --- a/ts/components/SignalConnectionsModal.stories.tsx +++ b/ts/components/SignalConnectionsModal.stories.tsx @@ -1,9 +1,10 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './SignalConnectionsModal'; import enMessages from '../../_locales/en/messages.json'; import { SignalConnectionsModal } from './SignalConnectionsModal'; @@ -14,16 +15,16 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/SignalConnectionsModal', component: SignalConnectionsModal, - argTypes: { - i18n: { - defaultValue: i18n, - }, - onClose: { action: true }, + args: { + i18n, + onClose: action('onClose'), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ( + +); export const Modal = Template.bind({}); Modal.args = {}; diff --git a/ts/components/SignalConnectionsModal.tsx b/ts/components/SignalConnectionsModal.tsx index 6db2824831..552c6e53ba 100644 --- a/ts/components/SignalConnectionsModal.tsx +++ b/ts/components/SignalConnectionsModal.tsx @@ -7,7 +7,6 @@ import type { LocalizerType } from '../types/Util'; import { Button, ButtonVariant } from './Button'; import { Intl } from './Intl'; import { Modal } from './Modal'; -import { STORIES_COLOR_THEME } from './Stories'; export type PropsType = { i18n: LocalizerType; @@ -24,7 +23,6 @@ export function SignalConnectionsModal({ hasXButton i18n={i18n} onClose={onClose} - theme={STORIES_COLOR_THEME} >
diff --git a/ts/components/Slider.stories.tsx b/ts/components/Slider.stories.tsx index 897641df0b..c998aae130 100644 --- a/ts/components/Slider.stories.tsx +++ b/ts/components/Slider.stories.tsx @@ -5,12 +5,13 @@ import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './Slider'; import { Slider } from './Slider'; export default { title: 'Components/Slider', -}; +} satisfies Meta; const createProps = (): PropsType => ({ label: 'Slider Handle', diff --git a/ts/components/Spinner.stories.tsx b/ts/components/Spinner.stories.tsx index bd73aa4e75..eeda198765 100644 --- a/ts/components/Spinner.stories.tsx +++ b/ts/components/Spinner.stories.tsx @@ -2,58 +2,43 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - -import { select, text } from '@storybook/addon-knobs'; +import type { Meta } from '@storybook/react'; import type { Props } from './Spinner'; import { Spinner, SpinnerDirections, SpinnerSvgSizes } from './Spinner'; export default { title: 'Components/Spinner', -}; + argTypes: { + size: { control: { type: 'text' } }, + svgSize: { control: { type: 'select' }, options: SpinnerSvgSizes }, + direction: { control: { type: 'select' }, options: SpinnerDirections }, + }, + args: { + size: '20px', + svgSize: 'normal', + direction: undefined, + }, +} satisfies Meta; -const createProps = (overrideProps: Partial = {}): Props => ({ - size: text('size', overrideProps.size || ''), - svgSize: select( - 'svgSize', - SpinnerSvgSizes.reduce((m, s) => ({ ...m, [s]: s }), {}), - overrideProps.svgSize || 'normal' - ), - direction: select( - 'direction', - SpinnerDirections.reduce((d, s) => ({ ...d, [s]: s }), {}), - overrideProps.direction - ), -}); - -export function Normal(): JSX.Element { - const props = createProps(); - - return ; +export function Normal(args: Props): JSX.Element { + return ; } -export function SvgSizes(): JSX.Element { - const props = createProps(); - +export function SvgSizes(args: Props): JSX.Element { return ( <> {SpinnerSvgSizes.map(svgSize => ( - + ))} ); } -SvgSizes.story = { - name: 'SVG Sizes', -}; - -export function Directions(): JSX.Element { - const props = createProps(); - +export function Directions(args: Props): JSX.Element { return ( <> {SpinnerDirections.map(direction => ( - + ))} ); diff --git a/ts/components/StandaloneRegistration.tsx b/ts/components/StandaloneRegistration.tsx index 81de522c05..6253cba3d0 100644 --- a/ts/components/StandaloneRegistration.tsx +++ b/ts/components/StandaloneRegistration.tsx @@ -10,6 +10,7 @@ import { strictAssert } from '../util/assert'; import * as log from '../logging/log'; import { parseNumber } from '../util/libphonenumberUtil'; import { getChallengeURL } from '../challenge'; +import { VerificationTransport } from '../types/VerificationTransport'; function PhoneInput({ onValidation, @@ -100,11 +101,15 @@ export function StandaloneRegistration({ }: { onComplete: () => void; requestVerification: ( - type: 'sms' | 'voice', number: string, - token: string + captcha: string, + transport: VerificationTransport + ) => Promise<{ sessionId: string }>; + registerSingleDevice: ( + number: string, + code: string, + sessionId: string ) => Promise; - registerSingleDevice: (number: string, code: string) => Promise; }): JSX.Element { useEffect(() => { window.IPC.readyForUpdates(); @@ -115,10 +120,11 @@ export function StandaloneRegistration({ const [number, setNumber] = useState(undefined); const [code, setCode] = useState(''); const [error, setError] = useState(undefined); + const [sessionId, setSessionId] = useState(undefined); const [status, setStatus] = useState(undefined); const onRequestCode = useCallback( - async (type: 'sms' | 'voice') => { + async (transport: VerificationTransport) => { if (!isValidNumber) { return; } @@ -141,7 +147,8 @@ export function StandaloneRegistration({ }); try { - void requestVerification(type, number, token); + const result = await requestVerification(number, token, transport); + setSessionId(result.sessionId); setError(undefined); } catch (err) { setError(err.message); @@ -155,7 +162,7 @@ export function StandaloneRegistration({ e.preventDefault(); e.stopPropagation(); - void onRequestCode('sms'); + void onRequestCode(VerificationTransport.SMS); }, [onRequestCode] ); @@ -165,7 +172,7 @@ export function StandaloneRegistration({ e.preventDefault(); e.stopPropagation(); - void onRequestCode('voice'); + void onRequestCode(VerificationTransport.Voice); }, [onRequestCode] ); @@ -185,14 +192,14 @@ export function StandaloneRegistration({ event.preventDefault(); event.stopPropagation(); - if (!isValidNumber || !isValidCode) { + if (!isValidNumber || !isValidCode || !sessionId) { return; } strictAssert(number != null && code.length > 0, 'Missing number or code'); try { - await registerSingleDevice(number, code); + await registerSingleDevice(number, code, sessionId); onComplete(); } catch (err) { setStatus(err.message); @@ -203,6 +210,7 @@ export function StandaloneRegistration({ onComplete, number, code, + sessionId, setStatus, isValidNumber, isValidCode, diff --git a/ts/components/Stories.tsx b/ts/components/Stories.tsx deleted file mode 100644 index 41dbf82ce4..0000000000 --- a/ts/components/Stories.tsx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2022 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React, { useState } from 'react'; -import classNames from 'classnames'; -import type { - ConversationType, - ShowConversationType, -} from '../state/ducks/conversations'; -import type { - ConversationStoryType, - MyStoryType, - StoryViewType, -} from '../types/Stories'; -import type { LocalizerType } from '../types/Util'; -import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; -import type { ShowToastAction } from '../state/ducks/toast'; -import type { - AddStoryData, - ViewUserStoriesActionCreatorType, - ViewStoryActionCreatorType, -} from '../state/ducks/stories'; -import { MyStories } from './MyStories'; -import { StoriesPane } from './StoriesPane'; -import { Theme, themeClassName } from '../util/theme'; -import { getWidthFromPreferredWidth } from '../util/leftPaneWidth'; -import { useEscapeHandling } from '../hooks/useEscapeHandling'; - -export type PropsType = { - addStoryData: AddStoryData; - deleteStoryForEveryone: (story: StoryViewType) => unknown; - getPreferredBadge: PreferredBadgeSelectorType; - hasViewReceiptSetting: boolean; - hiddenStories: Array; - i18n: LocalizerType; - isStoriesSettingsVisible: boolean; - isViewingStory: boolean; - maxAttachmentSizeInKb: number; - me: ConversationType; - myStories: Array; - onForwardStory: (storyId: string) => unknown; - onSaveStory: (story: StoryViewType) => unknown; - onMediaPlaybackStart: () => void; - preferredWidthFromStorage: number; - queueStoryDownload: (storyId: string) => unknown; - renderStoryCreator: () => JSX.Element; - retryMessageSend: (messageId: string) => unknown; - setAddStoryData: (data: AddStoryData) => unknown; - showConversation: ShowConversationType; - showStoriesSettings: () => unknown; - showToast: ShowToastAction; - stories: Array; - toggleHideStories: (conversationId: string) => unknown; - toggleStoriesView: () => unknown; - viewStory: ViewStoryActionCreatorType; - viewUserStories: ViewUserStoriesActionCreatorType; -}; - -export const STORIES_COLOR_THEME = Theme.Dark; - -export function Stories({ - addStoryData, - deleteStoryForEveryone, - getPreferredBadge, - hasViewReceiptSetting, - hiddenStories, - i18n, - isStoriesSettingsVisible, - isViewingStory, - maxAttachmentSizeInKb, - me, - myStories, - onForwardStory, - onSaveStory, - onMediaPlaybackStart, - preferredWidthFromStorage, - queueStoryDownload, - renderStoryCreator, - retryMessageSend, - setAddStoryData, - showConversation, - showStoriesSettings, - showToast, - stories, - toggleHideStories, - toggleStoriesView, - viewStory, - viewUserStories, -}: PropsType): JSX.Element { - const width = getWidthFromPreferredWidth(preferredWidthFromStorage, { - requiresFullWidth: true, - }); - - const [isMyStories, setIsMyStories] = useState(false); - - // only handle ESC if not showing a child that handles their own ESC - useEscapeHandling( - (isMyStories && myStories.length) || - isViewingStory || - isStoriesSettingsVisible || - addStoryData - ? undefined - : toggleStoriesView - ); - - return ( -
- {addStoryData && renderStoryCreator()} -
- {isMyStories && myStories.length ? ( - setIsMyStories(false)} - onDelete={deleteStoryForEveryone} - onForward={onForwardStory} - onSave={onSaveStory} - onMediaPlaybackStart={onMediaPlaybackStart} - queueStoryDownload={queueStoryDownload} - retryMessageSend={retryMessageSend} - viewStory={viewStory} - /> - ) : ( - - file - ? setAddStoryData({ type: 'Media', file }) - : setAddStoryData({ type: 'Text' }) - } - onMyStoriesClicked={() => { - if (myStories.length) { - setIsMyStories(true); - } else { - setAddStoryData({ type: 'Text' }); - } - }} - onStoriesSettings={showStoriesSettings} - onMediaPlaybackStart={onMediaPlaybackStart} - queueStoryDownload={queueStoryDownload} - showConversation={showConversation} - showToast={showToast} - stories={stories} - toggleHideStories={toggleHideStories} - toggleStoriesView={toggleStoriesView} - viewUserStories={viewUserStories} - /> - )} -
-
-
- {i18n('icu:Stories__placeholder--text')} -
-
- ); -} diff --git a/ts/components/StoriesAddStoryButton.tsx b/ts/components/StoriesAddStoryButton.tsx index 477f0bfd12..fe300dc411 100644 --- a/ts/components/StoriesAddStoryButton.tsx +++ b/ts/components/StoriesAddStoryButton.tsx @@ -7,7 +7,6 @@ import React, { useState, useCallback } from 'react'; import type { LocalizerType } from '../types/Util'; import type { ShowToastAction } from '../state/ducks/toast'; import { ContextMenu } from './ContextMenu'; -import { Theme } from '../util/theme'; import { ToastType } from '../types/Toast'; import { isVideoGoodForStories, @@ -109,7 +108,6 @@ export function StoriesAddStoryButton({ placement: 'bottom', strategy: 'absolute', }} - theme={Theme.Dark} > {children} diff --git a/ts/components/StoriesPane.tsx b/ts/components/StoriesPane.tsx index 518398d206..bbb614a697 100644 --- a/ts/components/StoriesPane.tsx +++ b/ts/components/StoriesPane.tsx @@ -10,18 +10,15 @@ import type { ShowConversationType, } from '../state/ducks/conversations'; import type { ConversationStoryType, MyStoryType } from '../types/Stories'; -import type { LocalizerType } from '../types/Util'; +import type { LocalizerType, ThemeType } from '../types/Util'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { ShowToastAction } from '../state/ducks/toast'; import type { ViewUserStoriesActionCreatorType } from '../state/ducks/stories'; -import { ContextMenu } from './ContextMenu'; import { MyStoryButton } from './MyStoryButton'; import { SearchInput } from './SearchInput'; -import { StoriesAddStoryButton } from './StoriesAddStoryButton'; import { StoryListItem } from './StoryListItem'; -import { Theme } from '../util/theme'; import { isNotNil } from '../util/isNotNil'; -import { useRestoreFocus } from '../hooks/useRestoreFocus'; +import { NavSidebarSearchHeader } from './NavSidebar'; const FUSE_OPTIONS: Fuse.IFuseOptions = { getFn: (story, path) => { @@ -70,8 +67,8 @@ export type PropsType = { showConversation: ShowConversationType; showToast: ShowToastAction; stories: Array; + theme: ThemeType; toggleHideStories: (conversationId: string) => unknown; - toggleStoriesView: () => unknown; viewUserStories: ViewUserStoriesActionCreatorType; }; @@ -84,14 +81,13 @@ export function StoriesPane({ myStories, onAddStory, onMyStoriesClicked, - onStoriesSettings, onMediaPlaybackStart, queueStoryDownload, showConversation, showToast, stories, + theme, toggleHideStories, - toggleStoriesView, viewUserStories, }: PropsType): JSX.Element { const [searchTerm, setSearchTerm] = useState(''); @@ -106,55 +102,18 @@ export function StoriesPane({ setRenderedStories(stories); } }, [searchTerm, stories]); - - const [focusRef] = useRestoreFocus(); - return ( <> -
-
- { - setSearchTerm(event.target.value); - }} - placeholder={i18n('icu:search')} - value={searchTerm} - /> +
{ showConversation({ conversationId }); - toggleStoriesView(); }} onHideStory={toggleHideStories} onMediaPlaybackStart={onMediaPlaybackStart} queueStoryDownload={queueStoryDownload} story={story.storyView} + theme={theme} viewUserStories={viewUserStories} /> ))} @@ -191,6 +150,7 @@ export function StoriesPane({ <>
)} @@ -1239,7 +1254,9 @@ type GroupStorySettingsModalProps = { group: ConversationType; onClose(): void; onBackButtonClick(): void; - getConversationByUuid(uuid: UUIDStringType): ConversationType | undefined; + getConversationByServiceId( + serviceId: ServiceIdString + ): ConversationType | undefined; onRemoveGroup(group: ConversationType): void; }; @@ -1248,10 +1265,13 @@ export function GroupStorySettingsModal({ group, onClose, onBackButtonClick, - getConversationByUuid, + getConversationByServiceId, onRemoveGroup, }: GroupStorySettingsModalProps): JSX.Element { - const groupMemberships = getGroupMemberships(group, getConversationByUuid); + const groupMemberships = getGroupMemberships( + group, + getConversationByServiceId + ); return ( undefined, + hiddenStories: [], + i18n, + maxAttachmentSizeInKb: 100 * 1024, + me: getDefaultConversation(), + myStories: [], + onForwardStory: action('onForwardStory'), + onSaveStory: action('onSaveStory'), + preferredWidthFromStorage: 380, + queueStoryDownload: action('queueStoryDownload'), + renderStoryCreator: () => <>StoryCreator, + retryMessageSend: action('retryMessageSend'), + showConversation: action('showConversation'), + showStoriesSettings: action('showStoriesSettings'), + showToast: action('showToast'), + stories: [], + toggleHideStories: action('toggleHideStories'), + viewUserStories: action('viewUserStories'), + viewStory: action('viewStory'), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const Blank = Template.bind({}); Blank.args = {}; diff --git a/ts/components/StoriesTab.tsx b/ts/components/StoriesTab.tsx new file mode 100644 index 0000000000..b914bb7be4 --- /dev/null +++ b/ts/components/StoriesTab.tsx @@ -0,0 +1,217 @@ +// Copyright 2022 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import React, { useState } from 'react'; +import type { + ConversationType, + ShowConversationType, +} from '../state/ducks/conversations'; +import type { + ConversationStoryType, + MyStoryType, + StoryViewType, +} from '../types/Stories'; +import type { LocalizerType, ThemeType } from '../types/Util'; +import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; +import type { ShowToastAction } from '../state/ducks/toast'; +import type { + AddStoryData, + ViewUserStoriesActionCreatorType, + ViewStoryActionCreatorType, +} from '../state/ducks/stories'; +import { MyStories } from './MyStories'; +import { StoriesPane } from './StoriesPane'; +import { NavSidebar, NavSidebarActionButton } from './NavSidebar'; +import { StoriesAddStoryButton } from './StoriesAddStoryButton'; +import { ContextMenu } from './ContextMenu'; +import type { UnreadStats } from '../util/countUnreadStats'; + +export type PropsType = { + addStoryData: AddStoryData; + otherTabsUnreadStats: UnreadStats; + deleteStoryForEveryone: (story: StoryViewType) => unknown; + getPreferredBadge: PreferredBadgeSelectorType; + hasFailedStorySends: boolean; + hasPendingUpdate: boolean; + hasViewReceiptSetting: boolean; + hiddenStories: Array; + i18n: LocalizerType; + isStoriesSettingsVisible: boolean; + isViewingStory: boolean; + maxAttachmentSizeInKb: number; + me: ConversationType; + myStories: Array; + navTabsCollapsed: boolean; + onForwardStory: (storyId: string) => unknown; + onSaveStory: (story: StoryViewType) => unknown; + onToggleNavTabsCollapse: (navTabsCollapsed: boolean) => void; + onMediaPlaybackStart: () => void; + preferredLeftPaneWidth: number; + preferredWidthFromStorage: number; + queueStoryDownload: (storyId: string) => unknown; + renderStoryCreator: () => JSX.Element; + retryMessageSend: (messageId: string) => unknown; + savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void; + setAddStoryData: (data: AddStoryData) => unknown; + showConversation: ShowConversationType; + showStoriesSettings: () => unknown; + showToast: ShowToastAction; + stories: Array; + theme: ThemeType; + toggleHideStories: (conversationId: string) => unknown; + viewStory: ViewStoryActionCreatorType; + viewUserStories: ViewUserStoriesActionCreatorType; +}; + +export function StoriesTab({ + addStoryData, + otherTabsUnreadStats, + deleteStoryForEveryone, + getPreferredBadge, + hasFailedStorySends, + hasPendingUpdate, + hasViewReceiptSetting, + hiddenStories, + i18n, + maxAttachmentSizeInKb, + me, + myStories, + navTabsCollapsed, + onForwardStory, + onSaveStory, + onToggleNavTabsCollapse, + onMediaPlaybackStart, + preferredLeftPaneWidth, + queueStoryDownload, + renderStoryCreator, + retryMessageSend, + savePreferredLeftPaneWidth, + setAddStoryData, + showConversation, + showStoriesSettings, + showToast, + stories, + theme, + toggleHideStories, + viewStory, + viewUserStories, +}: PropsType): JSX.Element { + const [isMyStories, setIsMyStories] = useState(false); + + function onAddStory(file?: File) { + if (file) { + setAddStoryData({ type: 'Media', file }); + } else { + setAddStoryData({ type: 'Text' }); + } + } + + return ( +
+ {addStoryData && renderStoryCreator()} + {isMyStories && myStories.length ? ( + setIsMyStories(false)} + onDelete={deleteStoryForEveryone} + onForward={onForwardStory} + onSave={onSaveStory} + onMediaPlaybackStart={onMediaPlaybackStart} + onToggleNavTabsCollapse={onToggleNavTabsCollapse} + preferredLeftPaneWidth={preferredLeftPaneWidth} + queueStoryDownload={queueStoryDownload} + retryMessageSend={retryMessageSend} + savePreferredLeftPaneWidth={savePreferredLeftPaneWidth} + theme={theme} + viewStory={viewStory} + /> + ) : ( + + + + {({ openMenu, onKeyDown }) => { + return ( + } + label={i18n('icu:StoriesTab__MoreActionsLabel')} + /> + ); + }} + + + } + > + { + if (myStories.length) { + setIsMyStories(true); + } else { + setAddStoryData({ type: 'Text' }); + } + }} + onStoriesSettings={showStoriesSettings} + onMediaPlaybackStart={onMediaPlaybackStart} + queueStoryDownload={queueStoryDownload} + showConversation={showConversation} + showToast={showToast} + stories={stories} + theme={theme} + toggleHideStories={toggleHideStories} + viewUserStories={viewUserStories} + /> + + )} +
+
+ {i18n('icu:Stories__placeholder--text')} +
+
+ ); +} diff --git a/ts/components/StoryCreator.stories.tsx b/ts/components/StoryCreator.stories.tsx index 35f35aaa2b..ff1f7720f3 100644 --- a/ts/components/StoryCreator.stories.tsx +++ b/ts/components/StoryCreator.stories.tsx @@ -1,9 +1,10 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './StoryCreator'; import enMessages from '../../_locales/en/messages.json'; import { StoryCreator } from './StoryCreator'; @@ -20,71 +21,46 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/StoryCreator', component: StoryCreator, - argTypes: { - candidateConversations: { - defaultValue: Array.from(Array(100), getDefaultConversation), - }, - debouncedMaybeGrabLinkPreview: { action: true }, - distributionLists: { defaultValue: getFakeDistributionListsWithMembers() }, - getPreferredBadge: { action: true }, - groupConversations: { - defaultValue: Array.from(Array(7), getDefaultGroup), - }, - groupStories: { - defaultValue: Array.from(Array(4), getDefaultGroup), - }, - hasFirstStoryPostExperience: { - defaultValue: false, - }, - i18n: { defaultValue: i18n }, + args: { + candidateConversations: Array.from(Array(100), getDefaultConversation), + debouncedMaybeGrabLinkPreview: action('debouncedMaybeGrabLinkPreview'), + distributionLists: getFakeDistributionListsWithMembers(), + getPreferredBadge: () => undefined, + groupConversations: Array.from(Array(7), getDefaultGroup), + groupStories: Array.from(Array(4), getDefaultGroup), + hasFirstStoryPostExperience: false, + i18n, imageToBlurHash: async () => 'LDA,FDBnm+I=p{tkIUI;~UkpELV]', - installedPacks: { - defaultValue: [], - }, - isSending: { - defaultValue: false, - }, - linkPreview: { - defaultValue: undefined, - }, - me: { - defaultValue: getDefaultConversation(), - }, - onClose: { action: true }, - onDeleteList: { action: true }, - onDistributionListCreated: { action: true }, - onHideMyStoriesFrom: { action: true }, - onSend: { action: true }, - onSetSkinTone: { action: true }, - onUseEmoji: { action: true }, - onViewersUpdated: { action: true }, - processAttachment: { action: true }, - recentEmojis: { - defaultValue: [], - }, - recentStickers: { - defaultValue: [], - }, - sendStoryModalOpenStateChanged: { action: true }, - setMyStoriesToAllSignalConnections: { action: true }, - signalConnections: { - defaultValue: Array.from(Array(42), getDefaultConversation), - }, - skinTone: { - defaultValue: 0, - }, - toggleSignalConnectionsModal: { action: true }, + installedPacks: [], + isSending: false, + linkPreview: undefined, + me: getDefaultConversation(), + onClose: action('onClose'), + onDeleteList: action('onDeleteList'), + onDistributionListCreated: undefined, + onHideMyStoriesFrom: action('onHideMyStoriesFrom'), + onSend: action('onSend'), + onSetSkinTone: action('onSetSkinTone'), + onUseEmoji: action('onUseEmoji'), + onViewersUpdated: action('onViewersUpdated'), + processAttachment: undefined, + recentEmojis: [], + recentStickers: [], + sendStoryModalOpenStateChanged: action('sendStoryModalOpenStateChanged'), + setMyStoriesToAllSignalConnections: action( + 'setMyStoriesToAllSignalConnections' + ), + signalConnections: Array.from(Array(42), getDefaultConversation), + skinTone: 0, + toggleSignalConnectionsModal: action('toggleSignalConnectionsModal'), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const Default = Template.bind({}); Default.args = {}; -Default.story = { - name: 'w/o Link Preview available', -}; export const LinkPreview = Template.bind({}); LinkPreview.args = { @@ -97,17 +73,11 @@ LinkPreview.args = { url: 'https://www.catsandkittens.lolcats/kittens/page/1', }, }; -LinkPreview.story = { - name: 'with Link Preview ready to be applied', -}; export const FirstTime = Template.bind({}); FirstTime.args = { hasFirstStoryPostExperience: true, }; -FirstTime.story = { - name: 'First time posting a story', -}; export const Sending = Template.bind({}); Sending.args = { diff --git a/ts/components/StoryCreator.tsx b/ts/components/StoryCreator.tsx index 54647fae15..8255b78aa5 100644 --- a/ts/components/StoryCreator.tsx +++ b/ts/components/StoryCreator.tsx @@ -4,18 +4,20 @@ import React, { useEffect, useState } from 'react'; import { get, has } from 'lodash'; +import { createPortal } from 'react-dom'; import type { AttachmentType, InMemoryAttachmentDraftType, } from '../types/Attachment'; import type { LinkPreviewSourceType } from '../types/LinkPreview'; import type { LinkPreviewType } from '../types/message/LinkPreviews'; -import type { LocalizerType } from '../types/Util'; +import type { LocalizerType, ThemeType } from '../types/Util'; import type { Props as StickerButtonProps } from './stickers/StickerButton'; import type { PropsType as SendStoryModalPropsType } from './SendStoryModal'; -import type { UUIDStringType } from '../types/UUID'; +import type { StoryDistributionIdString } from '../types/StoryDistributionId'; import type { imageToBlurHash } from '../util/imageToBlurHash'; import type { PropsType as TextStoryCreatorPropsType } from './TextStoryCreator'; +import type { PropsType as MediaEditorPropsType } from './MediaEditor'; import { TEXT_ATTACHMENT } from '../types/MIME'; import { isVideoAttachment } from '../types/Attachment'; @@ -23,9 +25,24 @@ import { SendStoryModal } from './SendStoryModal'; import { MediaEditor } from './MediaEditor'; import { TextStoryCreator } from './TextStoryCreator'; -import type { SmartCompositionTextAreaProps } from '../state/smart/CompositionTextArea'; import type { DraftBodyRanges } from '../types/BodyRange'; +function usePortalElement(testid: string): HTMLDivElement | null { + const [element, setElement] = useState(null); + + useEffect(() => { + const div = document.createElement('div'); + div.dataset.testid = testid; + document.body.appendChild(div); + setElement(div); + return () => { + document.body.removeChild(div); + }; + }, [testid]); + + return element; +} + export type PropsType = { debouncedMaybeGrabLinkPreview: ( message: string, @@ -37,7 +54,7 @@ export type PropsType = { linkPreview?: LinkPreviewType; onClose: () => unknown; onSend: ( - listIds: Array, + listIds: Array, conversationIds: Array, attachment: AttachmentType, bodyRanges: DraftBodyRanges | undefined @@ -46,10 +63,8 @@ export type PropsType = { processAttachment: ( file: File ) => Promise; - renderCompositionTextArea: ( - props: SmartCompositionTextAreaProps - ) => JSX.Element; sendStoryModalOpenStateChanged: (isOpen: boolean) => unknown; + theme: ThemeType; } & Pick & Pick< SendStoryModalPropsType, @@ -78,6 +93,15 @@ export type PropsType = { Pick< TextStoryCreatorPropsType, 'onUseEmoji' | 'skinTone' | 'onSetSkinTone' | 'recentEmojis' + > & + Pick< + MediaEditorPropsType, + | 'isFormattingEnabled' + | 'isFormattingFlagEnabled' + | 'isFormattingSpoilersFlagEnabled' + | 'onPickEmoji' + | 'onTextTooLong' + | 'platform' >; export function StoryCreator({ @@ -92,6 +116,9 @@ export function StoryCreator({ i18n, imageToBlurHash, installedPacks, + isFormattingEnabled, + isFormattingFlagEnabled, + isFormattingSpoilersFlagEnabled, isSending, linkPreview, me, @@ -100,26 +127,31 @@ export function StoryCreator({ onDeleteList, onDistributionListCreated, onHideMyStoriesFrom, + onMediaPlaybackStart, + onPickEmoji, onRemoveMembers, onRepliesNReactionsChanged, onSelectedStoryList, onSend, onSetSkinTone, + onTextTooLong, onUseEmoji, onViewersUpdated, - onMediaPlaybackStart, ourConversationId, + platform, processAttachment, recentEmojis, recentStickers, - renderCompositionTextArea, sendStoryModalOpenStateChanged, setMyStoriesToAllSignalConnections, signalConnections, skinTone, + theme, toggleGroupsForStorySend, toggleSignalConnectionsModal, -}: PropsType): JSX.Element { +}: PropsType): JSX.Element | null { + const portalElement = usePortalElement('StoryCreatorPortal'); + const [draftAttachment, setDraftAttachment] = useState< AttachmentType | undefined >(); @@ -173,97 +205,107 @@ export function StoryCreator({ } }, [draftAttachment, sendStoryModalOpenStateChanged]); - return ( - <> - {draftAttachment && isReadyToSend && ( - setDraftAttachment(undefined)} - onDeleteList={onDeleteList} - onDistributionListCreated={onDistributionListCreated} - onHideMyStoriesFrom={onHideMyStoriesFrom} - onRemoveMembers={onRemoveMembers} - onRepliesNReactionsChanged={onRepliesNReactionsChanged} - onSelectedStoryList={onSelectedStoryList} - onSend={(listIds, groupIds) => { - onSend(listIds, groupIds, draftAttachment, bodyRanges); - setDraftAttachment(undefined); - }} - onViewersUpdated={onViewersUpdated} - onMediaPlaybackStart={onMediaPlaybackStart} - setMyStoriesToAllSignalConnections={ - setMyStoriesToAllSignalConnections - } - signalConnections={signalConnections} - toggleGroupsForStorySend={toggleGroupsForStorySend} - mostRecentActiveStoryTimestampByGroupOrDistributionList={ - mostRecentActiveStoryTimestampByGroupOrDistributionList - } - toggleSignalConnectionsModal={toggleSignalConnectionsModal} - /> - )} - {draftAttachment && !isReadyToSend && attachmentUrl && ( - { - setDraftAttachment({ - ...draftAttachment, - contentType, - data, - size: data.byteLength, - blurHash, - caption, - }); - setBodyRanges(captionBodyRanges); - setIsReadyToSend(true); - }} - recentStickers={recentStickers} - /> - )} - {!file && ( - { - setDraftAttachment({ - contentType: TEXT_ATTACHMENT, - textAttachment, - size: textAttachment.text?.length || 0, - }); - setIsReadyToSend(true); - }} - onUseEmoji={onUseEmoji} - onSetSkinTone={onSetSkinTone} - recentEmojis={recentEmojis} - skinTone={skinTone} - /> - )} - - ); + return portalElement != null + ? createPortal( + <> + {draftAttachment && isReadyToSend && ( + setIsReadyToSend(false)} + onDeleteList={onDeleteList} + onDistributionListCreated={onDistributionListCreated} + onHideMyStoriesFrom={onHideMyStoriesFrom} + onRemoveMembers={onRemoveMembers} + onRepliesNReactionsChanged={onRepliesNReactionsChanged} + onSelectedStoryList={onSelectedStoryList} + onSend={(listIds, groupIds) => { + onSend(listIds, groupIds, draftAttachment, bodyRanges); + setDraftAttachment(undefined); + }} + onViewersUpdated={onViewersUpdated} + onMediaPlaybackStart={onMediaPlaybackStart} + setMyStoriesToAllSignalConnections={ + setMyStoriesToAllSignalConnections + } + signalConnections={signalConnections} + toggleGroupsForStorySend={toggleGroupsForStorySend} + mostRecentActiveStoryTimestampByGroupOrDistributionList={ + mostRecentActiveStoryTimestampByGroupOrDistributionList + } + theme={theme} + toggleSignalConnectionsModal={toggleSignalConnectionsModal} + /> + )} + {draftAttachment && attachmentUrl && ( + { + setDraftAttachment({ + ...draftAttachment, + contentType, + data, + size: data.byteLength, + blurHash, + caption, + }); + setBodyRanges(captionBodyRanges); + setIsReadyToSend(true); + }} + onPickEmoji={onPickEmoji} + onTextTooLong={onTextTooLong} + platform={platform} + recentStickers={recentStickers} + skinTone={skinTone} + /> + )} + {!file && ( + { + setDraftAttachment({ + contentType: TEXT_ATTACHMENT, + textAttachment, + size: textAttachment.text?.length || 0, + }); + setIsReadyToSend(true); + }} + onUseEmoji={onUseEmoji} + onSetSkinTone={onSetSkinTone} + recentEmojis={recentEmojis} + skinTone={skinTone} + /> + )} + , + portalElement + ) + : null; } diff --git a/ts/components/StoryDetailsModal.stories.tsx b/ts/components/StoryDetailsModal.stories.tsx index 50b42db17f..63b9e7e6ca 100644 --- a/ts/components/StoryDetailsModal.stories.tsx +++ b/ts/components/StoryDetailsModal.stories.tsx @@ -1,15 +1,15 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; import casual from 'casual'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './StoryDetailsModal'; import enMessages from '../../_locales/en/messages.json'; import { SendStatus } from '../messages/MessageSendState'; import { StoryDetailsModal } from './StoryDetailsModal'; -import { fakeAttachment } from '../test-both/helpers/fakeAttachment'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import { setupI18n } from '../util/setupI18n'; @@ -18,29 +18,18 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/StoryDetailsModal', component: StoryDetailsModal, - argTypes: { - getPreferredBadge: { action: true }, - i18n: { - defaultValue: i18n, - }, - onClose: { action: true }, - sender: { - defaultValue: getDefaultConversation(), - }, - sendState: { - defaultValue: undefined, - }, - size: { - defaultValue: fakeAttachment().size, - }, - timestamp: { - defaultValue: Date.now(), - }, + args: { + getPreferredBadge: () => undefined, + i18n, + onClose: action('onClose'), + sender: getDefaultConversation(), + sendState: undefined, + timestamp: Date.now(), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const MyStory = Template.bind({}); MyStory.args = { diff --git a/ts/components/StoryDistributionListName.tsx b/ts/components/StoryDistributionListName.tsx index 3f3fd617e3..8301aaf698 100644 --- a/ts/components/StoryDistributionListName.tsx +++ b/ts/components/StoryDistributionListName.tsx @@ -5,11 +5,12 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { getStoryDistributionListName } from '../types/Stories'; +import type { StoryDistributionIdString } from '../types/StoryDistributionId'; import { UserText } from './UserText'; type PropsType = { i18n: LocalizerType; - id: string; + id: StoryDistributionIdString | string; name: string; }; diff --git a/ts/components/StoryImage.stories.tsx b/ts/components/StoryImage.stories.tsx index e50c6b47cd..909a4fe536 100644 --- a/ts/components/StoryImage.stories.tsx +++ b/ts/components/StoryImage.stories.tsx @@ -6,6 +6,7 @@ import { v4 as uuid } from 'uuid'; import { action } from '@storybook/addon-actions'; import { noop } from 'lodash'; +import type { Meta } from '@storybook/react'; import type { PropsType } from './StoryImage'; import { StoryImage } from './StoryImage'; import enMessages from '../../_locales/en/messages.json'; @@ -20,7 +21,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/StoryImage', -}; +} satisfies Meta; function getDefaultProps(): PropsType { return { @@ -41,26 +42,14 @@ export function GoodStory(): JSX.Element { return ; } -GoodStory.story = { - name: 'Good story', -}; - export function GoodStoryThumbnail(): JSX.Element { return ; } -GoodStoryThumbnail.story = { - name: 'Good story (thumbnail)', -}; - export function NotDownloaded(): JSX.Element { return ; } -NotDownloaded.story = { - name: 'Not downloaded', -}; - export function NotDownloadedThumbnail(): JSX.Element { return ( { + log.error( + 'StoryImage: Failed to play video', + Errors.toLogFormat(error) + ); + }); } }, [isPaused, onMediaPlaybackStart]); diff --git a/ts/components/StoryLinkPreview.stories.tsx b/ts/components/StoryLinkPreview.stories.tsx index 8bffcea296..b46ba21e41 100644 --- a/ts/components/StoryLinkPreview.stories.tsx +++ b/ts/components/StoryLinkPreview.stories.tsx @@ -1,7 +1,7 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; import type { Props } from './StoryLinkPreview'; @@ -21,35 +21,23 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/StoryLinkPreview', component: StoryLinkPreview, - argTypes: { - description: { - defaultValue: - 'Introducing Mac Studio. Stunningly compact. Endless connectivity. And astonishing performance with M1 Max or the new M1 Ultra chip.', - }, - forceCompactMode: { - defaultValue: false, - }, - i18n: { - defaultValue: i18n, - }, - image: { - defaultValue: fakeAttachment({ - // url: 'https://www.apple.com/v/mac-studio/c/images/meta/mac-studio_overview__eedzbosm1t26_og.png', - url: '/fixtures/kitten-4-112-112.jpg', - contentType: IMAGE_JPEG, - }), - }, - title: { - defaultValue: 'Mac Studio', - }, - url: { - defaultValue: 'https://www.apple.com/mac-studio/', - }, + args: { + description: + 'Introducing Mac Studio. Stunningly compact. Endless connectivity. And astonishing performance with M1 Max or the new M1 Ultra chip.', + forceCompactMode: false, + i18n, + image: fakeAttachment({ + // url: 'https://www.apple.com/v/mac-studio/c/images/meta/mac-studio_overview__eedzbosm1t26_og.png', + url: '/fixtures/kitten-4-112-112.jpg', + contentType: IMAGE_JPEG, + }), + title: 'Mac Studio', + url: 'https://www.apple.com/mac-studio/', }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const Default = Template.bind({}); diff --git a/ts/components/StoryListItem.stories.tsx b/ts/components/StoryListItem.stories.tsx index 14c85c49cb..4a2f0d97b4 100644 --- a/ts/components/StoryListItem.stories.tsx +++ b/ts/components/StoryListItem.stories.tsx @@ -1,9 +1,10 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './StoryListItem'; import { StoryListItem } from './StoryListItem'; import enMessages from '../../_locales/en/messages.json'; @@ -19,30 +20,26 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/StoryListItem', component: StoryListItem, - argTypes: { - conversationId: { - defaultValue: getDefaultConversation().id, - }, - getPreferredBadge: { action: true }, - i18n: { - defaultValue: i18n, - }, - onGoToConversation: { action: true }, - onHideStory: { action: true }, - queueStoryDownload: { action: true }, + args: { + conversationId: getDefaultConversation().id, + getPreferredBadge: () => undefined, + i18n, + onGoToConversation: action('onGoToConversation'), + onHideStory: action('onHideStory'), + queueStoryDownload: action('queueStoryDownload'), story: { - defaultValue: { - messageId: '123', - sender: getDefaultConversation(), - timestamp: Date.now(), - }, + messageId: '123', + sender: getDefaultConversation(), + timestamp: Date.now(), + messageIdForLogging: '123', + expirationTimestamp: undefined, }, - viewUserStories: { action: true }, + viewUserStories: action('viewUserStories'), }, -} as Meta; +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +const Template: StoryFn = args => ; export const SomeonesStory = Template.bind({}); SomeonesStory.args = { @@ -60,6 +57,3 @@ SomeonesStory.args = { expirationTimestamp: undefined, }, }; -SomeonesStory.story = { - name: "Someone's story", -}; diff --git a/ts/components/StoryListItem.tsx b/ts/components/StoryListItem.tsx index 66d620c2ae..5ab5ba2257 100644 --- a/ts/components/StoryListItem.tsx +++ b/ts/components/StoryListItem.tsx @@ -5,7 +5,7 @@ import React, { useState } from 'react'; import classNames from 'classnames'; import type { ConversationStoryType, StoryViewType } from '../types/Stories'; import type { ConversationType } from '../state/ducks/conversations'; -import type { LocalizerType } from '../types/Util'; +import type { LocalizerType, ThemeType } from '../types/Util'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { ViewUserStoriesActionCreatorType } from '../state/ducks/stories'; import { Avatar, AvatarSize } from './Avatar'; @@ -16,7 +16,6 @@ import { StoryViewTargetType, HasStories } from '../types/Stories'; import { MessageTimestamp } from './conversation/MessageTimestamp'; import { StoryImage } from './StoryImage'; -import { ThemeType } from '../types/Util'; import { getAvatarColor } from '../types/Colors'; export type PropsType = Pick & { @@ -30,6 +29,7 @@ export type PropsType = Pick & { queueStoryDownload: (storyId: string) => unknown; onMediaPlaybackStart: () => void; story: StoryViewType; + theme: ThemeType; viewUserStories: ViewUserStoriesActionCreatorType; }; @@ -45,6 +45,7 @@ function StoryListItemAvatar({ profileName, sharedGroupNames, title, + theme, }: Pick< ConversationType, | 'acceptedMessageRequest' @@ -59,6 +60,7 @@ function StoryListItemAvatar({ getPreferredBadge: PreferredBadgeSelectorType; i18n: LocalizerType; isMe?: boolean; + theme: ThemeType; }): JSX.Element { return ( ); @@ -92,6 +94,7 @@ export function StoryListItem({ onMediaPlaybackStart, queueStoryDownload, story, + theme, viewUserStories, }: PropsType): JSX.Element { const [hasConfirmHideStory, setHasConfirmHideStory] = useState(false); @@ -100,7 +103,7 @@ export function StoryListItem({ const { firstName, title } = sender; - const isSignalOfficial = sender.uuid === SIGNAL_ACI; + const isSignalOfficial = sender.serviceId === SIGNAL_ACI; let avatarStoryRing: HasStories | undefined; if (attachment) { @@ -167,13 +170,14 @@ export function StoryListItem({ avatarStoryRing={avatarStoryRing} getPreferredBadge={getPreferredBadge} i18n={i18n} + theme={theme} {...(group || sender)} />
{group ? group.title : title} {isSignalOfficial && ( - + )}
{!isSignalOfficial && ( diff --git a/ts/components/StoryViewer.stories.tsx b/ts/components/StoryViewer.stories.tsx index 254d3dad94..a049c3ac77 100644 --- a/ts/components/StoryViewer.stories.tsx +++ b/ts/components/StoryViewer.stories.tsx @@ -1,19 +1,21 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta } from '@storybook/react'; import React from 'react'; - +import { action } from '@storybook/addon-actions'; import type { PropsType } from './StoryViewer'; import enMessages from '../../_locales/en/messages.json'; import { SendStatus } from '../messages/MessageSendState'; import { StoryViewModeType } from '../types/Stories'; +import { generateStoryDistributionId } from '../types/StoryDistributionId'; import { StoryViewer } from './StoryViewer'; import { VIDEO_MP4 } from '../types/MIME'; import { fakeAttachment } from '../test-both/helpers/fakeAttachment'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import { getFakeStoryView } from '../test-both/helpers/getFakeStory'; import { setupI18n } from '../util/setupI18n'; +import { DEFAULT_PREFERRED_REACTION_EMOJI } from '../reactions/constants'; const i18n = setupI18n('en', enMessages); @@ -21,238 +23,237 @@ export default { title: 'Components/StoryViewer', component: StoryViewer, argTypes: { - currentIndex: { - defaultvalue: 0, - }, - getPreferredBadge: { action: true }, - group: { - defaultValue: undefined, - }, - hasAllStoriesMuted: { + hasAllStoriesUnmuted: { control: 'boolean', - defaultValue: false, }, hasViewReceiptSetting: { control: 'boolean', - defaultValue: true, }, - i18n: { - defaultValue: i18n, - }, - platform: { - defaultValue: 'darwin', - }, - loadStoryReplies: { action: true }, - markStoryRead: { action: true }, - numStories: { - defaultValue: 1, - }, - onGoToConversation: { action: true }, - onHideStory: { action: true }, - onReactToStory: { action: true }, - onReplyToStory: { action: true }, - onSetSkinTone: { action: true }, - onTextTooLong: { action: true }, - onUseEmoji: { action: true }, - preferredReactionEmoji: { - defaultValue: ['❀', '👍', '👎', '😂', '😼', '😱'], - }, - queueStoryDownload: { action: true }, - renderEmojiPicker: { action: true }, - retryMessageSend: { action: true }, - showToast: { action: true }, - skinTone: { - defaultValue: 0, - }, - story: { - defaultValue: getFakeStoryView(), - }, - storyViewMode: { - defaultValue: StoryViewModeType.All, - }, - toggleHasAllStoriesMuted: { action: true }, - viewStory: { action: true }, - isWindowActive: { defaultValue: true }, }, args: { currentIndex: 0, + getPreferredBadge: () => undefined, + group: undefined, + hasAllStoriesUnmuted: true, + hasViewReceiptSetting: true, + i18n, + platform: 'darwin', + loadStoryReplies: action('loadStoryReplies'), + markStoryRead: action('markStoryRead'), + numStories: 1, + onGoToConversation: action('onGoToConversation'), + onHideStory: action('onHideStory'), + onReactToStory: action('onReactToStory'), + onReplyToStory: action('onReplyToStory'), + onSetSkinTone: action('onSetSkinTone'), + onTextTooLong: action('onTextTooLong'), + onUseEmoji: action('onUseEmoji'), + onMediaPlaybackStart: action('onMediaPlaybackStart'), + preferredReactionEmoji: DEFAULT_PREFERRED_REACTION_EMOJI, + queueStoryDownload: action('queueStoryDownload'), + renderEmojiPicker: () => <>EmojiPicker, + retryMessageSend: action('retryMessageSend'), + showToast: action('showToast'), + skinTone: 0, + story: getFakeStoryView(), + storyViewMode: StoryViewModeType.All, + viewStory: action('viewStory'), + isWindowActive: true, }, -} as Meta; +} satisfies Meta; -// eslint-disable-next-line react/function-component-definition -const Template: Story = args => ; +export function SomeonesStory(args: PropsType): JSX.Element { + return ; +} -export const SomeonesStory = Template.bind({}); -SomeonesStory.args = {}; -SomeonesStory.story = { - name: "Someone's story", -}; +export function WideStory(args: PropsType): JSX.Element { + return ( + + ); +} -export const WideStory = Template.bind({}); -WideStory.args = { - story: getFakeStoryView('/fixtures/nathan-anderson-316188-unsplash.jpg'), -}; -WideStory.story = { - name: 'Wide story', -}; +export function InAGroup(args: PropsType): JSX.Element { + return ( + + ); +} -export const InAGroup = Template.bind({}); -InAGroup.args = { - group: getDefaultConversation({ - avatarPath: '/fixtures/kitten-4-112-112.jpg', - title: 'Family Group', - type: 'group', - }), -}; -InAGroup.story = { - name: 'In a group', -}; +export function MultiStory(args: PropsType): JSX.Element { + return ( + + ); +} -export const MultiStory = Template.bind({}); -MultiStory.args = { - currentIndex: 2, - numStories: 7, - story: { - ...getFakeStoryView(), - attachment: fakeAttachment({ - contentType: VIDEO_MP4, - fileName: 'pixabay-Soap-Bubble-7141.mp4', - url: '/fixtures/kitten-4-112-112.jpg', - screenshotPath: '/fixtures/kitten-4-112-112.jpg', - }), - }, -}; -MultiStory.story = { - name: 'Multi story', -}; +export function Caption(args: PropsType): JSX.Element { + return ( + + ); +} -export const Caption = Template.bind({}); -Caption.args = { - story: { - ...getFakeStoryView(), - attachment: fakeAttachment({ - caption: 'This place looks lovely', - path: 'file.jpg', - url: '/fixtures/nathan-anderson-316188-unsplash.jpg', - }), - }, -}; +export function EmojiCaption(args: PropsType): JSX.Element { + return ( + + ); +} -export const EmojiCaption = Template.bind({}); -EmojiCaption.args = { - story: { - ...getFakeStoryView(), - attachment: fakeAttachment({ - caption: 'WOOOOOOOOW đŸ„°', - path: 'file.jpg', - url: '/fixtures/nathan-anderson-316188-unsplash.jpg', - }), - }, -}; +export function LongCaption(args: PropsType): JSX.Element { + return ( + + ); +} -export const LongCaption = Template.bind({}); -LongCaption.args = { - story: { - ...getFakeStoryView(), - 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', - }), - }, -}; +export function YourStory(args: PropsType): JSX.Element { + const storyView = getFakeStoryView( + '/fixtures/nathan-anderson-316188-unsplash.jpg' + ); + return ( + + ); +} -export const YourStory = Template.bind({}); -{ +export function YourStoryFailed(args: PropsType): JSX.Element { const storyView = getFakeStoryView( '/fixtures/nathan-anderson-316188-unsplash.jpg' ); - YourStory.args = { - distributionList: { id: '123', name: 'Close Friends' }, - story: { - ...storyView, - sender: { - ...storyView.sender, - isMe: true, - }, - sendState: [ - { - recipient: getDefaultConversation(), - status: SendStatus.Viewed, + return ( + + ); } -export const YourStoryFailed = Template.bind({}); -{ +export function ReadReceiptsOff(args: PropsType): JSX.Element { const storyView = getFakeStoryView( '/fixtures/nathan-anderson-316188-unsplash.jpg' ); - - YourStoryFailed.args = { - distributionList: { id: '123', name: 'Close Friends' }, - story: { - ...storyView, - sender: { - ...storyView.sender, - isMe: true, - }, - sendState: [ - { - recipient: getDefaultConversation(), - status: SendStatus.Viewed, + return ( + ); - ReadReceiptsOff.args = { - hasViewReceiptSetting: false, - story: { - ...storyView, - sender: { - ...storyView.sender, - isMe: true, - }, - sendState: [ - { - recipient: getDefaultConversation(), - status: SendStatus.Viewed, - }, - { - recipient: getDefaultConversation(), - status: SendStatus.Delivered, - }, - { - recipient: getDefaultConversation(), - status: SendStatus.Pending, - }, - ], - }, - }; } -ReadReceiptsOff.storyName = 'Read receipts turned off'; diff --git a/ts/components/StoryViewer.tsx b/ts/components/StoryViewer.tsx index a374c890eb..66f0b18283 100644 --- a/ts/components/StoryViewer.tsx +++ b/ts/components/StoryViewer.tsx @@ -21,6 +21,7 @@ import type { EmojiPickDataType } from './emoji/EmojiPicker'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { RenderEmojiPickerProps } from './conversation/ReactionPicker'; import type { ReplyStateType, StoryViewType } from '../types/Stories'; +import type { StoryDistributionIdString } from '../types/StoryDistributionId'; import type { ShowToastAction } from '../state/ducks/toast'; import type { ViewStoryActionCreatorType } from '../state/ducks/stories'; import * as log from '../logging/log'; @@ -66,7 +67,7 @@ export type PropsType = { deleteGroupStoryReply: (id: string) => void; deleteGroupStoryReplyForEveryone: (id: string) => void; deleteStoryForEveryone: (story: StoryViewType) => unknown; - distributionList?: { id: string; name: string }; + distributionList?: { id: StoryDistributionIdString; name: string }; getPreferredBadge: PreferredBadgeSelectorType; group?: Pick< ConversationType, diff --git a/ts/components/StoryViewsNRepliesModal.stories.tsx b/ts/components/StoryViewsNRepliesModal.stories.tsx index 88e4953984..8a429a78eb 100644 --- a/ts/components/StoryViewsNRepliesModal.stories.tsx +++ b/ts/components/StoryViewsNRepliesModal.stories.tsx @@ -1,19 +1,21 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; +import { v4 as generateUuid } from 'uuid'; import { useArgs } from '@storybook/addons'; +import { action } from '@storybook/addon-actions'; import type { PropsType } from './StoryViewsNRepliesModal'; import * as durations from '../util/durations'; import enMessages from '../../_locales/en/messages.json'; import { SendStatus } from '../messages/MessageSendState'; import { StoryViewsNRepliesModal } from './StoryViewsNRepliesModal'; -import { UUID } from '../types/UUID'; import { getDefaultConversation } from '../test-both/helpers/getDefaultConversation'; import { setupI18n } from '../util/setupI18n'; import { StoryViewTargetType } from '../types/Stories'; +import { DEFAULT_PREFERRED_REACTION_EMOJI } from '../reactions/constants'; const i18n = setupI18n('en', enMessages); @@ -21,51 +23,35 @@ export default { title: 'Components/StoryViewsNRepliesModal', component: StoryViewsNRepliesModal, argTypes: { - authorTitle: { - defaultValue: getDefaultConversation().title, - }, - canReply: { - defaultValue: true, - }, - getPreferredBadge: { action: true }, hasViewReceiptSetting: { control: 'boolean', - defaultValue: true, }, hasViewsCapability: { control: 'boolean', - defaultValue: false, - }, - i18n: { - defaultValue: i18n, - }, - platform: { - defaultValue: 'darwin', - }, - onClose: { action: true }, - onSetSkinTone: { action: true }, - onReact: { action: true }, - onReply: { action: true }, - onTextTooLong: { action: true }, - onUseEmoji: { action: true }, - preferredReactionEmoji: { - defaultValue: ['❀', '👍', '👎', '😂', '😼', '😱'], - }, - renderEmojiPicker: { action: true }, - replies: { - defaultValue: [], - }, - views: { - defaultValue: [], - }, - viewTarget: { - defaultValue: StoryViewTargetType.Views, - }, - onChangeViewTarget: { - action: true, }, }, -} as Meta; + args: { + authorTitle: getDefaultConversation().title, + canReply: true, + getPreferredBadge: () => undefined, + hasViewReceiptSetting: true, + hasViewsCapability: false, + i18n, + platform: 'darwin', + onClose: action('onClose'), + onSetSkinTone: action('onSetSkinTone'), + onReact: action('onReact'), + onReply: action('onReply'), + onTextTooLong: action('onTextTooLong'), + onUseEmoji: action('onUseEmoji'), + preferredReactionEmoji: DEFAULT_PREFERRED_REACTION_EMOJI, + renderEmojiPicker: () => <>EmojiPicker, + replies: [], + views: [], + viewTarget: StoryViewTargetType.Views, + onChangeViewTarget: action('onChangeViewTarget'), + }, +} satisfies Meta; function getViewsAndReplies() { const p1 = getDefaultConversation(); @@ -110,34 +96,34 @@ function getViewsAndReplies() { author: p2, body: 'So cute ❀', conversationId: p2.id, - id: UUID.generate().toString(), + id: generateUuid(), timestamp: Date.now() - 24 * durations.MINUTE, }, { author: p3, body: "That's awesome", conversationId: p3.id, - id: UUID.generate().toString(), + id: generateUuid(), timestamp: Date.now() - 13 * durations.MINUTE, }, { author: p3, body: 'Very awesome', conversationId: p3.id, - id: UUID.generate().toString(), + id: generateUuid(), timestamp: Date.now() - 13 * durations.MINUTE, }, { author: p3, body: 'Did I mention how awesome this is?', conversationId: p3.id, - id: UUID.generate().toString(), + id: generateUuid(), timestamp: Date.now() - 12 * durations.MINUTE, }, { author: p4, conversationId: p4.id, - id: UUID.generate().toString(), + id: generateUuid(), reactionEmoji: '❀', timestamp: Date.now() - 5 * durations.MINUTE, }, @@ -145,7 +131,7 @@ function getViewsAndReplies() { author: p6, body: 'Thanks everyone!', conversationId: p6.id, - id: UUID.generate().toString(), + id: generateUuid(), sendStateByConversationId: { [p1.id]: { status: SendStatus.Pending, @@ -162,7 +148,7 @@ function getViewsAndReplies() { } // eslint-disable-next-line react/function-component-definition -const Template: Story = args => { +const Template: StoryFn = args => { const [, updateArgs] = useArgs(); function onChangeViewTarget(viewTarget: StoryViewTargetType) { diff --git a/ts/components/TextAttachment.stories.tsx b/ts/components/TextAttachment.stories.tsx index 0a2624406b..34a967e999 100644 --- a/ts/components/TextAttachment.stories.tsx +++ b/ts/components/TextAttachment.stories.tsx @@ -3,6 +3,7 @@ import React from 'react'; +import type { Meta } from '@storybook/react'; import enMessages from '../../_locales/en/messages.json'; import { setupI18n } from '../util/setupI18n'; import { TextAttachment } from './TextAttachment'; @@ -17,7 +18,7 @@ const getDefaultProps = (): PropsType => ({ export default { title: 'Components/TextAttachment', -}; +} satisfies Meta; export function SolidBgTextBg(): JSX.Element { return ( @@ -34,10 +35,6 @@ export function SolidBgTextBg(): JSX.Element { ); } -SolidBgTextBg.story = { - name: 'Solid bg + text bg', -}; - export function Gradient(): JSX.Element { return ( ; + +export function Defaults(args: PropsType): JSX.Element { + return ; +} + +export function Long(args: PropsType): JSX.Element { + return ( + + Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis deserunt + cupiditate doloribus vitae perspiciatis, eos atque mollitia aliquam quae + aspernatur et iure vero illo veritatis quibusdam maiores laborum. + Inventore, minus. + + ); +} diff --git a/ts/components/ToastAlreadyRequestedToJoin.stories.tsx b/ts/components/ToastAlreadyRequestedToJoin.stories.tsx index b8d61e7335..01f397d33f 100644 --- a/ts/components/ToastAlreadyRequestedToJoin.stories.tsx +++ b/ts/components/ToastAlreadyRequestedToJoin.stories.tsx @@ -3,6 +3,8 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastAlreadyRequestedToJoin'; import { ToastAlreadyRequestedToJoin } from './ToastAlreadyRequestedToJoin'; import { setupI18n } from '../util/setupI18n'; @@ -17,12 +19,8 @@ const defaultProps = { export default { title: 'Components/ToastAlreadyRequestedToJoin', -}; +} satisfies Meta; export const _ToastAlreadyRequestedToJoin = (): JSX.Element => ( ); - -_ToastAlreadyRequestedToJoin.story = { - name: 'ToastAlreadyRequestedToJoin', -}; diff --git a/ts/components/ToastAlreadyRequestedToJoin.tsx b/ts/components/ToastAlreadyRequestedToJoin.tsx index 5a38cc2c56..a35af96724 100644 --- a/ts/components/ToastAlreadyRequestedToJoin.tsx +++ b/ts/components/ToastAlreadyRequestedToJoin.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastCaptchaFailed.stories.tsx b/ts/components/ToastCaptchaFailed.stories.tsx index 8cada788fb..7592b59c0a 100644 --- a/ts/components/ToastCaptchaFailed.stories.tsx +++ b/ts/components/ToastCaptchaFailed.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastCaptchaFailed'; import { ToastCaptchaFailed } from './ToastCaptchaFailed'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastCaptchaFailed', -}; +} satisfies Meta; export const _ToastCaptchaFailed = (): JSX.Element => ( ); - -_ToastCaptchaFailed.story = { - name: 'ToastCaptchaFailed', -}; diff --git a/ts/components/ToastCaptchaFailed.tsx b/ts/components/ToastCaptchaFailed.tsx index 907982181d..1fd0dd64e1 100644 --- a/ts/components/ToastCaptchaFailed.tsx +++ b/ts/components/ToastCaptchaFailed.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastCaptchaSolved.stories.tsx b/ts/components/ToastCaptchaSolved.stories.tsx index 8fba3fa66e..838b997899 100644 --- a/ts/components/ToastCaptchaSolved.stories.tsx +++ b/ts/components/ToastCaptchaSolved.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastCaptchaSolved'; import { ToastCaptchaSolved } from './ToastCaptchaSolved'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastCaptchaSolved', -}; +} satisfies Meta; export const _ToastCaptchaSolved = (): JSX.Element => ( ); - -_ToastCaptchaSolved.story = { - name: 'ToastCaptchaSolved', -}; diff --git a/ts/components/ToastCaptchaSolved.tsx b/ts/components/ToastCaptchaSolved.tsx index 3d18dfada6..1b410fb1cc 100644 --- a/ts/components/ToastCaptchaSolved.tsx +++ b/ts/components/ToastCaptchaSolved.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastDebugLogError.stories.tsx b/ts/components/ToastDebugLogError.stories.tsx index 419e8eb928..0197d49d86 100644 --- a/ts/components/ToastDebugLogError.stories.tsx +++ b/ts/components/ToastDebugLogError.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastDebugLogError'; import { ToastDebugLogError } from './ToastDebugLogError'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastDebugLogError', -}; +} satisfies Meta; export const _ToastDebugLogError = (): JSX.Element => ( ); - -_ToastDebugLogError.story = { - name: 'ToastDebugLogError', -}; diff --git a/ts/components/ToastDebugLogError.tsx b/ts/components/ToastDebugLogError.tsx index 10765032d1..c0c7f95a34 100644 --- a/ts/components/ToastDebugLogError.tsx +++ b/ts/components/ToastDebugLogError.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastFileSize.stories.tsx b/ts/components/ToastFileSize.stories.tsx index 4641897d8d..eeca4dbb4d 100644 --- a/ts/components/ToastFileSize.stories.tsx +++ b/ts/components/ToastFileSize.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastFileSize'; import { ToastFileSize } from './ToastFileSize'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastFileSize', -}; +} satisfies Meta; export const _ToastFileSize = (): JSX.Element => ( ); - -_ToastFileSize.story = { - name: 'ToastFileSize', -}; diff --git a/ts/components/ToastFileSize.tsx b/ts/components/ToastFileSize.tsx index 6baf2f26f8..76675693f3 100644 --- a/ts/components/ToastFileSize.tsx +++ b/ts/components/ToastFileSize.tsx @@ -10,7 +10,7 @@ export type ToastPropsType = { units: string; }; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; } & ToastPropsType; diff --git a/ts/components/ToastGroupLinkCopied.stories.tsx b/ts/components/ToastGroupLinkCopied.stories.tsx index 905342faf5..5598c690dc 100644 --- a/ts/components/ToastGroupLinkCopied.stories.tsx +++ b/ts/components/ToastGroupLinkCopied.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastGroupLinkCopied'; import { ToastGroupLinkCopied } from './ToastGroupLinkCopied'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastGroupLinkCopied', -}; +} satisfies Meta; export const _ToastGroupLinkCopied = (): JSX.Element => ( ); - -_ToastGroupLinkCopied.story = { - name: 'ToastGroupLinkCopied', -}; diff --git a/ts/components/ToastGroupLinkCopied.tsx b/ts/components/ToastGroupLinkCopied.tsx index d660ad69d9..e24adfdaf4 100644 --- a/ts/components/ToastGroupLinkCopied.tsx +++ b/ts/components/ToastGroupLinkCopied.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastInternalError.stories.tsx b/ts/components/ToastInternalError.stories.tsx index edc512cdd6..39b27e4d2f 100644 --- a/ts/components/ToastInternalError.stories.tsx +++ b/ts/components/ToastInternalError.stories.tsx @@ -3,11 +3,12 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastInternalError'; import { ToastInternalError, ToastInternalErrorKind, } from './ToastInternalError'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -21,7 +22,7 @@ const defaultProps = { export default { title: 'Components/ToastInternalError', -}; +} satisfies Meta; export function ToastDecryptionError(): JSX.Element { return ( @@ -34,10 +35,6 @@ export function ToastDecryptionError(): JSX.Element { ); } -ToastDecryptionError.story = { - name: 'ToastDecryptionError', -}; - export function ToastCDSMirroringError(): JSX.Element { return ( ); } - -ToastDecryptionError.story = { - name: 'ToastCDSMirroringError', -}; diff --git a/ts/components/ToastInternalError.tsx b/ts/components/ToastInternalError.tsx index 4aaf1239f0..d65c3557dc 100644 --- a/ts/components/ToastInternalError.tsx +++ b/ts/components/ToastInternalError.tsx @@ -24,7 +24,7 @@ export type ToastPropsType = { } ); -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; } & ToastPropsType; diff --git a/ts/components/ToastLinkCopied.stories.tsx b/ts/components/ToastLinkCopied.stories.tsx index 3cdec4e44b..48f83e16ca 100644 --- a/ts/components/ToastLinkCopied.stories.tsx +++ b/ts/components/ToastLinkCopied.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastLinkCopied'; import { ToastLinkCopied } from './ToastLinkCopied'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastLinkCopied', -}; +} satisfies Meta; export const _ToastLinkCopied = (): JSX.Element => ( ); - -_ToastLinkCopied.story = { - name: 'ToastLinkCopied', -}; diff --git a/ts/components/ToastLinkCopied.tsx b/ts/components/ToastLinkCopied.tsx index cf9fceb57f..d4c30b6516 100644 --- a/ts/components/ToastLinkCopied.tsx +++ b/ts/components/ToastLinkCopied.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastLoadingFullLogs.stories.tsx b/ts/components/ToastLoadingFullLogs.stories.tsx index 04499d47d0..b242468ad9 100644 --- a/ts/components/ToastLoadingFullLogs.stories.tsx +++ b/ts/components/ToastLoadingFullLogs.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastLoadingFullLogs'; import { ToastLoadingFullLogs } from './ToastLoadingFullLogs'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastLoadingFullLogs', -}; +} satisfies Meta; export const _ToastLoadingFullLogs = (): JSX.Element => ( ); - -_ToastLoadingFullLogs.story = { - name: 'ToastLoadingFullLogs', -}; diff --git a/ts/components/ToastLoadingFullLogs.tsx b/ts/components/ToastLoadingFullLogs.tsx index e2b4504c32..bfd6cd081f 100644 --- a/ts/components/ToastLoadingFullLogs.tsx +++ b/ts/components/ToastLoadingFullLogs.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastManager.stories.tsx b/ts/components/ToastManager.stories.tsx index e5c53bb2a6..4efddb6e7a 100644 --- a/ts/components/ToastManager.stories.tsx +++ b/ts/components/ToastManager.stories.tsx @@ -1,9 +1,10 @@ // Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; import React from 'react'; +import { action } from '@storybook/addon-actions'; import enMessages from '../../_locales/en/messages.json'; import { ToastManager } from './ToastManager'; import type { AnyToast } from '../types/Toast'; @@ -26,6 +27,8 @@ function getToast(toastType: ToastType): AnyToast { return { toastType: ToastType.Blocked }; case ToastType.BlockedGroup: return { toastType: ToastType.BlockedGroup }; + case ToastType.CallHistoryCleared: + return { toastType: ToastType.CallHistoryCleared }; case ToastType.CannotEditMessage: return { toastType: ToastType.CannotEditMessage }; case ToastType.CannotForwardEmptyMessage: @@ -140,25 +143,23 @@ export default { title: 'Components/ToastManager', component: ToastManager, argTypes: { - hideToast: { action: true }, - openFileInFolder: { action: true }, - onUndoArchive: { action: true }, - i18n: { - defaultValue: i18n, - }, toastType: { - defaultValue: ToastType.AddingUserToGroup, options: ToastType, control: { type: 'select' }, }, - OS: { - defaultValue: 'macOS', - }, }, -} as Meta; + args: { + hideToast: action('hideToast'), + openFileInFolder: action('openFileInFolder'), + onUndoArchive: action('onUndoArchive'), + i18n, + toastType: ToastType.AddingUserToGroup, + OS: 'macOS', + }, +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => { +const Template: StoryFn = args => { const { toastType, ...rest } = args; return ( <> diff --git a/ts/components/ToastManager.tsx b/ts/components/ToastManager.tsx index 4f986c8e2c..fc8b850249 100644 --- a/ts/components/ToastManager.tsx +++ b/ts/components/ToastManager.tsx @@ -68,10 +68,18 @@ export function ToastManager({ return {i18n('icu:unblockGroupToSend')}; } + if (toastType === ToastType.CallHistoryCleared) { + return ( + + {i18n('icu:CallsTab__ToastCallHistoryCleared')} + + ); + } + if (toastType === ToastType.CannotEditMessage) { return ( - {i18n('icu:ToastManager__CannotEditMessage')} + {i18n('icu:ToastManager__CannotEditMessage_24')} ); } diff --git a/ts/components/ToastStickerPackInstallFailed.stories.tsx b/ts/components/ToastStickerPackInstallFailed.stories.tsx index 00fdf3e219..09ec721d3c 100644 --- a/ts/components/ToastStickerPackInstallFailed.stories.tsx +++ b/ts/components/ToastStickerPackInstallFailed.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastStickerPackInstallFailed'; import { ToastStickerPackInstallFailed } from './ToastStickerPackInstallFailed'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastStickerPackInstallFailed', -}; +} satisfies Meta; export const _ToastStickerPackInstallFailed = (): JSX.Element => ( ); - -_ToastStickerPackInstallFailed.story = { - name: 'ToastStickerPackInstallFailed', -}; diff --git a/ts/components/ToastStickerPackInstallFailed.tsx b/ts/components/ToastStickerPackInstallFailed.tsx index ac353d1444..e396a684b1 100644 --- a/ts/components/ToastStickerPackInstallFailed.tsx +++ b/ts/components/ToastStickerPackInstallFailed.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastVoiceNoteLimit.stories.tsx b/ts/components/ToastVoiceNoteLimit.stories.tsx index 5f9b2e7711..c3a29f5863 100644 --- a/ts/components/ToastVoiceNoteLimit.stories.tsx +++ b/ts/components/ToastVoiceNoteLimit.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastVoiceNoteLimit'; import { ToastVoiceNoteLimit } from './ToastVoiceNoteLimit'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastVoiceNoteLimit', -}; +} satisfies Meta; export const _ToastVoiceNoteLimit = (): JSX.Element => ( ); - -_ToastVoiceNoteLimit.story = { - name: 'ToastVoiceNoteLimit', -}; diff --git a/ts/components/ToastVoiceNoteLimit.tsx b/ts/components/ToastVoiceNoteLimit.tsx index 2b63e2e6db..a9d1e89dd4 100644 --- a/ts/components/ToastVoiceNoteLimit.tsx +++ b/ts/components/ToastVoiceNoteLimit.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/ToastVoiceNoteMustBeOnlyAttachment.stories.tsx b/ts/components/ToastVoiceNoteMustBeOnlyAttachment.stories.tsx index 4ce5f46e6e..4b71ce8796 100644 --- a/ts/components/ToastVoiceNoteMustBeOnlyAttachment.stories.tsx +++ b/ts/components/ToastVoiceNoteMustBeOnlyAttachment.stories.tsx @@ -3,8 +3,9 @@ import React from 'react'; import { action } from '@storybook/addon-actions'; +import type { Meta } from '@storybook/react'; +import type { PropsType } from './ToastVoiceNoteMustBeOnlyAttachment'; import { ToastVoiceNoteMustBeOnlyAttachment } from './ToastVoiceNoteMustBeOnlyAttachment'; - import { setupI18n } from '../util/setupI18n'; import enMessages from '../../_locales/en/messages.json'; @@ -17,12 +18,8 @@ const defaultProps = { export default { title: 'Components/ToastVoiceNoteMustBeOnlyAttachment', -}; +} satisfies Meta; export const _ToastVoiceNoteMustBeOnlyAttachment = (): JSX.Element => ( ); - -_ToastVoiceNoteMustBeOnlyAttachment.story = { - name: 'ToastVoiceNoteMustBeOnlyAttachment', -}; diff --git a/ts/components/ToastVoiceNoteMustBeOnlyAttachment.tsx b/ts/components/ToastVoiceNoteMustBeOnlyAttachment.tsx index 846598267f..f07f4cf367 100644 --- a/ts/components/ToastVoiceNoteMustBeOnlyAttachment.tsx +++ b/ts/components/ToastVoiceNoteMustBeOnlyAttachment.tsx @@ -5,7 +5,7 @@ import React from 'react'; import type { LocalizerType } from '../types/Util'; import { Toast } from './Toast'; -type PropsType = { +export type PropsType = { i18n: LocalizerType; onClose: () => unknown; }; diff --git a/ts/components/Tooltip.stories.tsx b/ts/components/Tooltip.stories.tsx index 4fb4c8e334..05165dc2fc 100644 --- a/ts/components/Tooltip.stories.tsx +++ b/ts/components/Tooltip.stories.tsx @@ -2,22 +2,32 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { select } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import type { PropsType } from './Tooltip'; import { Tooltip, TooltipPlacement } from './Tooltip'; import { Theme } from '../util/theme'; -const createProps = (overrideProps: Partial = {}): PropsType => ({ - content: overrideProps.content || 'Hello World', - direction: select('direction', TooltipPlacement, overrideProps.direction), - sticky: overrideProps.sticky, - theme: overrideProps.theme, -}); - export default { title: 'Components/Tooltip', -}; + argTypes: { + content: { control: { type: 'text' } }, + direction: { + control: { type: 'select' }, + options: Object.values(TooltipPlacement), + }, + sticky: { control: { type: 'boolean' } }, + theme: { + control: { type: 'select' }, + options: Object.keys(Theme), + mappings: Theme, + }, + }, + args: { + content: 'Hello World', + direction: TooltipPlacement.Top, + sticky: false, + }, +} satisfies Meta; const Trigger = ( ); -export const _Top = (): JSX.Element => ( - - {Trigger} - -); - -export const _Right = (): JSX.Element => ( - - {Trigger} - -); - -export const _Bottom = (): JSX.Element => ( - - {Trigger} - -); - -export const _Left = (): JSX.Element => ( - - {Trigger} - -); - -export function Sticky(): JSX.Element { +export function Top(args: PropsType): JSX.Element { return ( - + {Trigger} ); } -export function WithAppliedPopperModifiers(): JSX.Element { +export function Right(args: PropsType): JSX.Element { + return ( + + {Trigger} + + ); +} + +export function Bottom(args: PropsType): JSX.Element { + return ( + + {Trigger} + + ); +} + +export function Left(args: PropsType): JSX.Element { + return ( + + {Trigger} + + ); +} + +export function Sticky(args: PropsType): JSX.Element { + return ( + + {Trigger} + + ); +} + +export function WithAppliedPopperModifiers(args: PropsType): JSX.Element { return ( + {Trigger} ); diff --git a/ts/components/Tooltip.tsx b/ts/components/Tooltip.tsx index 2a40e87f99..3c42073338 100644 --- a/ts/components/Tooltip.tsx +++ b/ts/components/Tooltip.tsx @@ -1,7 +1,7 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React from 'react'; +import React, { useRef } from 'react'; import classNames from 'classnames'; import { noop } from 'lodash'; import { Manager, Reference, Popper } from 'react-popper'; @@ -89,8 +89,12 @@ export type PropsType = { sticky?: boolean; theme?: Theme; wrapperClassName?: string; + delay?: number; }; +let GLOBAL_EXIT_TIMER: NodeJS.Timeout | undefined; +let GLOBAL_TOOLTIP_DISABLE_DELAY = false; + export function Tooltip({ children, className, @@ -100,15 +104,56 @@ export function Tooltip({ theme, popperModifiers = [], wrapperClassName, + delay, }: PropsType): JSX.Element { - const [isHovering, setIsHovering] = React.useState(false); + const timeoutRef = useRef(); + const [active, setActive] = React.useState(false); - const showTooltip = isHovering || Boolean(sticky); + const showTooltip = active || Boolean(sticky); const tooltipThemeClassName = theme ? `module-tooltip--${themeClassName(theme)}` : undefined; + function handleHoverChanged(hovering: boolean) { + // Don't accept updates that aren't valid anymore + clearTimeout(GLOBAL_EXIT_TIMER); + clearTimeout(timeoutRef.current); + + // We can skip past all of this if there's no delay + if (delay != null) { + // If we're now hovering, and delays haven't been disabled globally + // we should start the timer to show the tooltip + if (hovering && !GLOBAL_TOOLTIP_DISABLE_DELAY) { + timeoutRef.current = setTimeout(() => { + setActive(true); + // Since we have shown a tooltip we can now disable these delays + // globally. + GLOBAL_TOOLTIP_DISABLE_DELAY = true; + }, delay); + return; + } + + if (!hovering) { + // If we're not hovering, we should hide the tooltip immediately + setActive(false); + + // If we've disabled delays globally, we need to start a timer to undo + // that after some time has passed. + if (GLOBAL_TOOLTIP_DISABLE_DELAY) { + GLOBAL_EXIT_TIMER = setTimeout(() => { + GLOBAL_TOOLTIP_DISABLE_DELAY = false; + + // We're always going to use 300 here so that a tooltip with a really + // long delay doesn't affect all of the others + }, 300); + } + return; + } + } + setActive(hovering); + } + return ( @@ -116,7 +161,7 @@ export function Tooltip({ {children} diff --git a/ts/components/UnsupportedOSDialog.stories.tsx b/ts/components/UnsupportedOSDialog.stories.tsx index 4392215d32..824cefccc0 100644 --- a/ts/components/UnsupportedOSDialog.stories.tsx +++ b/ts/components/UnsupportedOSDialog.stories.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - +import type { Meta } from '@storybook/react'; import { UnsupportedOSDialog } from './UnsupportedOSDialog'; import type { PropsType } from './UnsupportedOSDialog'; import { setupI18n } from '../util/setupI18n'; @@ -57,7 +57,7 @@ const permutations: ReadonlyArray<{ export default { title: 'Components/UnsupportedOSDialog', -}; +} satisfies Meta; export function Iterations(): JSX.Element { return ( diff --git a/ts/components/UsernameLinkModalBody.stories.tsx b/ts/components/UsernameLinkModalBody.stories.tsx index d02d32bf30..808cf808dc 100644 --- a/ts/components/UsernameLinkModalBody.stories.tsx +++ b/ts/components/UsernameLinkModalBody.stories.tsx @@ -2,8 +2,9 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useCallback, useState } from 'react'; -import type { Meta, Story } from '@storybook/react'; +import type { Meta, StoryFn } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; import enMessages from '../../_locales/en/messages.json'; import { UsernameLinkState } from '../state/ducks/usernameEnums'; import { setupI18n } from '../util/setupI18n'; @@ -21,26 +22,25 @@ export default { component: UsernameLinkModalBody, title: 'Components/UsernameLinkModalBody', argTypes: { - i18n: { - defaultValue: i18n, - }, link: { control: { type: 'text' }, - defaultValue: - 'https://signal.me#eu/n-AJkmmykrFB7j6UODGndSycxcMdp_v6ppRp9rFu5Ad39q_9Ngi_k9-TARWfT43t', }, username: { control: { type: 'text' }, - defaultValue: 'alice.12', + }, + usernameLinkCorrupted: { + control: 'boolean', }, usernameLinkState: { control: { type: 'select' }, - defaultValue: UsernameLinkState.Ready, - options: [UsernameLinkState.Ready, UsernameLinkState.Updating], + options: [ + UsernameLinkState.Ready, + UsernameLinkState.Updating, + UsernameLinkState.Error, + ], }, colorId: { control: { type: 'select' }, - defaultValue: ColorEnum.BLUE, mapping: { blue: ColorEnum.BLUE, white: ColorEnum.WHITE, @@ -52,16 +52,22 @@ export default { purple: ColorEnum.PURPLE, }, }, - showToast: { action: true }, - resetUsernameLink: { action: true }, - setUsernameLinkColor: { action: true }, }, -} as Meta; - -type ArgsType = PropsType; + args: { + i18n, + link: 'https://signal.me/#eu/n-AJkmmykrFB7j6UODGndSycxcMdp_v6ppRp9rFu5Ad39q_9Ngi_k9-TARWfT43t', + username: 'alice.12', + usernameLinkState: UsernameLinkState.Ready, + colorId: ColorEnum.BLUE, + showToast: action('showToast'), + resetUsernameLink: action('resetUsernameLink'), + setUsernameLinkColor: action('setUsernameLinkColor'), + onBack: action('onBack'), + }, +} satisfies Meta; // eslint-disable-next-line react/function-component-definition -const Template: Story = args => { +const Template: StoryFn = args => { const [attachment, setAttachment] = useState(); const saveAttachment = useCallback(({ data }: { data?: Uint8Array }) => { if (!data) { @@ -92,13 +98,6 @@ const Template: Story = args => { }; export const Normal = Template.bind({}); -Normal.args = {}; -Normal.story = { - name: 'normal', -}; export const NoLink = Template.bind({}); NoLink.args = { link: '' }; -NoLink.story = { - name: 'normal', -}; diff --git a/ts/components/UsernameLinkModalBody.tsx b/ts/components/UsernameLinkModalBody.tsx index 6dabd10e85..e29176cfc1 100644 --- a/ts/components/UsernameLinkModalBody.tsx +++ b/ts/components/UsernameLinkModalBody.tsx @@ -26,12 +26,14 @@ export type PropsType = Readonly<{ link?: string; username: string; colorId?: number; + usernameLinkCorrupted: boolean; usernameLinkState: UsernameLinkState; setUsernameLinkColor: (colorId: number) => void; resetUsernameLink: () => void; saveAttachment: SaveAttachmentActionCreatorType; showToast: ShowToastAction; + onBack: () => void; }>; export type ColorMapEntryType = Readonly<{ @@ -485,6 +487,7 @@ export function UsernameLinkModalBody({ i18n, link, username, + usernameLinkCorrupted, usernameLinkState, colorId: initialColorId = ColorEnum.UNKNOWN, @@ -492,10 +495,13 @@ export function UsernameLinkModalBody({ resetUsernameLink, saveAttachment, showToast, + + onBack, }: PropsType): JSX.Element { const [pngData, setPngData] = useState(); const [showColors, setShowColors] = useState(false); const [confirmReset, setConfirmReset] = useState(false); + const [showError, setShowError] = useState(false); const [colorId, setColorId] = useState(initialColorId); const { fg: fgColor, bg: bgColor } = COLOR_MAP.get(colorId) ?? DEFAULT_PRESET; @@ -618,13 +624,36 @@ export function UsernameLinkModalBody({ resetUsernameLink(); }, [resetUsernameLink]); + useEffect(() => { + if (!usernameLinkCorrupted) { + return; + } + + resetUsernameLink(); + }, [usernameLinkCorrupted, resetUsernameLink]); + + useEffect(() => { + if (usernameLinkState !== UsernameLinkState.Error) { + return; + } + + setShowError(true); + }, [usernameLinkState]); + + const onClearError = useCallback(() => { + setShowError(false); + }, []); + + const isResettingLink = + usernameLinkCorrupted || usernameLinkState !== UsernameLinkState.Ready; + const info = ( <>
@@ -663,9 +700,40 @@ export function UsernameLinkModalBody({ > {i18n('icu:UsernameLinkModalBody__reset')} + + ); + let linkImage: JSX.Element | undefined; + if (usernameLinkState === UsernameLinkState.Ready && link) { + linkImage = ( + <> + +
+ + ); + } else if (usernameLinkState === UsernameLinkState.Error) { + linkImage = ; + } else { + linkImage = ( + + ); + } + return (
@@ -675,23 +743,7 @@ export function UsernameLinkModalBody({ })} ref={onCardRef} > -
- {usernameLinkState === UsernameLinkState.Ready && link ? ( - <> - -
- - ) : ( - - )} -
+
{linkImage}
{!showColors && ( + )} {!conversation.isMe && ( <> {isMuted ? i18n('icu:unmute') : i18n('icu:mute')} - + {selectedNavTab !== NavTab.Calls && ( + + )}
+ {callHistoryGroup && ( + +
    + {callHistoryGroup.children.map(child => { + return ( +
  1. + + + {describeCallHistory( + i18n, + callHistoryGroup.type, + callHistoryGroup.direction, + callHistoryGroup.status + )} + + + {formatTime(i18n, child.timestamp, Date.now(), false)} + +
  2. + ); + })} +
+
+ )} + {!isGroup || canEditGroupInfo ? ( ) : null} - - } - label={i18n('icu:showChatColorEditor')} - onClick={() => { - pushPanelForConversation({ - type: PanelType.ChatColorEditor, - }); - }} - right={ -
- } - /> + {selectedNavTab === NavTab.Chats && ( + + } + label={i18n('icu:showChatColorEditor')} + onClick={() => { + pushPanelForConversation({ + type: PanelType.ChatColorEditor, + }); + }} + right={ +
+ } + /> + )} {isGroup && ( ; const createProps = (overrideProps: Partial = {}): Props => ({ acceptConversation: action('acceptConversation'), @@ -47,10 +46,6 @@ export function LeftTheGroup(): JSX.Element { return ; } -LeftTheGroup.story = { - name: 'Left the group', -}; - export function BlockedAndLeftTheGroup(): JSX.Element { const props = createProps({ left: true, @@ -61,32 +56,16 @@ export function BlockedAndLeftTheGroup(): JSX.Element { return ; } -BlockedAndLeftTheGroup.story = { - name: 'Blocked and left the group', -}; - export function CannotLeaveBecauseYouAreTheLastAdmin(): JSX.Element { const props = createProps({ cannotLeaveBecauseYouAreLastAdmin: true }); return ; } -CannotLeaveBecauseYouAreTheLastAdmin.story = { - name: 'Cannot leave because you are the last admin', -}; - export const _11 = (): JSX.Element => ( ); -_11.story = { - name: '1:1', -}; - export const _11Blocked = (): JSX.Element => ( ); - -_11Blocked.story = { - name: '1:1 Blocked', -}; diff --git a/ts/components/conversation/conversation-details/ConversationDetailsHeader.stories.tsx b/ts/components/conversation/conversation-details/ConversationDetailsHeader.stories.tsx index c538521412..606fd20247 100644 --- a/ts/components/conversation/conversation-details/ConversationDetailsHeader.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetailsHeader.stories.tsx @@ -2,17 +2,14 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; -import { number, text } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation'; import { getFakeBadges } from '../../../test-both/helpers/getFakeBadge'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; import { StorybookThemeContext } from '../../../../.storybook/StorybookThemeContext'; import type { ConversationType } from '../../../state/ducks/conversations'; - import type { Props } from './ConversationDetailsHeader'; import { ConversationDetailsHeader } from './ConversationDetailsHeader'; @@ -21,18 +18,17 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/ConversationDetailsHeader', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const createConversation = (): ConversationType => getDefaultConversation({ id: '', type: 'group', lastUpdated: 0, - title: text('conversation title', 'Some Conversation'), - groupDescription: text( - 'description', - 'This is a group description. https://www.signal.org' - ), + title: 'Some Conversation', + groupDescription: 'This is a group description. https://www.signal.org', }); function Wrapper(overrideProps: Partial) { @@ -45,7 +41,7 @@ function Wrapper(overrideProps: Partial) { i18n={i18n} canEdit={false} startEditing={action('startEditing')} - memberships={new Array(number('conversation members length', 0))} + memberships={new Array(0)} isGroup isMe={false} theme={theme} @@ -72,10 +68,6 @@ export function BasicNoDescription(): JSX.Element { ); } -BasicNoDescription.story = { - name: 'Basic no-description', -}; - export function EditableNoDescription(): JSX.Element { return ( ( - -); - -_11.story = { - name: '1:1', -}; +export function OneOnOne(): JSX.Element { + return ; +} export function NoteToSelf(): JSX.Element { return ; } - -NoteToSelf.story = { - name: 'Note to self', -}; diff --git a/ts/components/conversation/conversation-details/ConversationDetailsIcon.stories.tsx b/ts/components/conversation/conversation-details/ConversationDetailsIcon.stories.tsx index e48be8cc01..59da2abfb8 100644 --- a/ts/components/conversation/conversation-details/ConversationDetailsIcon.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetailsIcon.stories.tsx @@ -2,15 +2,14 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import type { Props } from './ConversationDetailsIcon'; import { ConversationDetailsIcon, IconType } from './ConversationDetailsIcon'; export default { title: 'Components/Conversation/ConversationDetails/ConversationDetailIcon', -}; +} satisfies Meta; const createProps = (overrideProps: Partial): Props => ({ ariaLabel: overrideProps.ariaLabel || '', diff --git a/ts/components/conversation/conversation-details/ConversationDetailsMediaList.stories.tsx b/ts/components/conversation/conversation-details/ConversationDetailsMediaList.stories.tsx index 41487341be..0ba75c5100 100644 --- a/ts/components/conversation/conversation-details/ConversationDetailsMediaList.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetailsMediaList.stories.tsx @@ -2,26 +2,24 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; - import type { Props } from './ConversationDetailsMediaList'; import { ConversationDetailsMediaList } from './ConversationDetailsMediaList'; +import type { MediaItemType } from '../../../types/MediaItem'; +import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation'; import { createPreparedMediaItems, createRandomMedia, -} from '../media-gallery/AttachmentSection.stories'; -import type { MediaItemType } from '../../../types/MediaItem'; -import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation'; +} from '../media-gallery/utils/mocks'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/ConversationMediaList', -}; +} satisfies Meta; const createProps = (mediaItems?: Array): Props => ({ conversation: getDefaultConversation({ diff --git a/ts/components/conversation/conversation-details/ConversationDetailsMediaList.tsx b/ts/components/conversation/conversation-details/ConversationDetailsMediaList.tsx index 02686d5669..11e3868cde 100644 --- a/ts/components/conversation/conversation-details/ConversationDetailsMediaList.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetailsMediaList.tsx @@ -19,7 +19,7 @@ export type Props = { loadRecentMediaItems: (id: string, limit: number) => void; showAllMedia: () => void; showLightboxWithMedia: ( - selectedAttachmentPath: string | undefined, + selectedIndex: number, media: ReadonlyArray> ) => void; }; @@ -66,9 +66,7 @@ export function ConversationDetailsMediaList({ key={`${mediaItem.message.id}-${mediaItem.index}`} mediaItem={mediaItem} i18n={i18n} - onClick={() => - showLightboxWithMedia(mediaItem.attachment.path, mediaItems) - } + onClick={() => showLightboxWithMedia(mediaItem.index, mediaItems)} /> ))}
diff --git a/ts/components/conversation/conversation-details/ConversationDetailsMembershipList.stories.tsx b/ts/components/conversation/conversation-details/ConversationDetailsMembershipList.stories.tsx index 099fba8be9..c2a5ef6a0f 100644 --- a/ts/components/conversation/conversation-details/ConversationDetailsMembershipList.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetailsMembershipList.stories.tsx @@ -2,11 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { isBoolean } from 'lodash'; - import { action } from '@storybook/addon-actions'; -import { number } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation'; @@ -23,14 +20,23 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/ConversationDetailsMembershipList', -}; + argTypes: {}, + args: { + canAddNewMembers: false, + conversationId: '123', + getPreferredBadge: () => undefined, + i18n, + memberships: [], + showContactModal: action('showContactModal'), + startAddingNewMembers: action('startAddingNewMembers'), + theme: ThemeType.light, + }, +} satisfies Meta; const createMemberships = ( numberOfMemberships = 10 ): Array => { - return Array.from( - new Array(number('number of memberships', numberOfMemberships)) - ).map( + return Array.from(new Array(numberOfMemberships)).map( (_, i): GroupV2Membership => ({ isAdmin: i % 3 === 0, member: getDefaultConversation({ @@ -40,81 +46,52 @@ const createMemberships = ( ); }; -const createProps = (overrideProps: Partial): Props => ({ - canAddNewMembers: isBoolean(overrideProps.canAddNewMembers) - ? overrideProps.canAddNewMembers - : false, - conversationId: '123', - getPreferredBadge: () => undefined, - i18n, - memberships: overrideProps.memberships || [], - showContactModal: action('showContactModal'), - startAddingNewMembers: action('startAddingNewMembers'), - theme: ThemeType.light, -}); - -export function Few(): JSX.Element { +export function Few(args: Props): JSX.Element { const memberships = createMemberships(3); - - const props = createProps({ memberships }); - - return ; + return ( + + ); } -export function Limit(): JSX.Element { +export function Limit(args: Props): JSX.Element { const memberships = createMemberships(5); - - const props = createProps({ memberships }); - - return ; + return ( + + ); } -export function Limit1(): JSX.Element { +export function Limit1(args: Props): JSX.Element { const memberships = createMemberships(6); - - const props = createProps({ memberships }); - - return ; + return ( + + ); } -Limit1.story = { - name: 'Limit +1', -}; - -export function Limit2(): JSX.Element { +export function Limit2(args: Props): JSX.Element { const memberships = createMemberships(7); - - const props = createProps({ memberships }); - - return ; + return ( + + ); } -Limit2.story = { - name: 'Limit +2', -}; - -export function Many(): JSX.Element { +export function Many(args: Props): JSX.Element { const memberships = createMemberships(100); - - const props = createProps({ memberships }); - - return ; + return ( + + ); } -export function None(): JSX.Element { - const props = createProps({ memberships: [] }); - - return ; +export function None(args: Props): JSX.Element { + return ; } -export function CanAddNewMembers(): JSX.Element { +export function CanAddNewMembers(args: Props): JSX.Element { const memberships = createMemberships(10); - - const props = createProps({ canAddNewMembers: true, memberships }); - - return ; + return ( + + ); } - -CanAddNewMembers.story = { - name: 'Can add new members', -}; diff --git a/ts/components/conversation/conversation-details/ConversationNotificationsSettings.stories.tsx b/ts/components/conversation/conversation-details/ConversationNotificationsSettings.stories.tsx index 22c529bae3..511cdd32b5 100644 --- a/ts/components/conversation/conversation-details/ConversationNotificationsSettings.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationNotificationsSettings.stories.tsx @@ -2,11 +2,11 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; +import type { PropsType } from './ConversationNotificationsSettings'; import { ConversationNotificationsSettings } from './ConversationNotificationsSettings'; const i18n = setupI18n('en', enMessages); @@ -14,7 +14,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/ConversationNotificationsSettings', -}; +} satisfies Meta; const getCommonProps = () => ({ id: 'conversation-id', @@ -30,10 +30,6 @@ export function GroupConversationAllDefault(): JSX.Element { return ; } -GroupConversationAllDefault.story = { - name: 'Group conversation, all default', -}; - export function GroupConversationMuted(): JSX.Element { return ( ); } - -GroupConversationMentionsMuted.story = { - name: 'Group conversation, @mentions muted', -}; diff --git a/ts/components/conversation/conversation-details/ConversationNotificationsSettings.tsx b/ts/components/conversation/conversation-details/ConversationNotificationsSettings.tsx index 2d0b0b243e..2c28cd76e6 100644 --- a/ts/components/conversation/conversation-details/ConversationNotificationsSettings.tsx +++ b/ts/components/conversation/conversation-details/ConversationNotificationsSettings.tsx @@ -14,7 +14,7 @@ import { getMuteOptions } from '../../../util/getMuteOptions'; import { parseIntOrThrow } from '../../../util/parseIntOrThrow'; import { useUniqueId } from '../../../hooks/useUniqueId'; -type PropsType = { +export type PropsType = { id: string; conversationType: ConversationTypeType; dontNotifyForMentionsIfMuted: boolean; diff --git a/ts/components/conversation/conversation-details/EditConversationAttributesModal.stories.tsx b/ts/components/conversation/conversation-details/EditConversationAttributesModal.stories.tsx index 07a13f63cf..d6a5626ab6 100644 --- a/ts/components/conversation/conversation-details/EditConversationAttributesModal.stories.tsx +++ b/ts/components/conversation/conversation-details/EditConversationAttributesModal.stories.tsx @@ -3,9 +3,8 @@ import type { ComponentProps } from 'react'; import React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; import { EditConversationAttributesModal } from './EditConversationAttributesModal'; @@ -16,7 +15,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/EditConversationAttributesModal', -}; +} satisfies Meta; type PropsType = ComponentProps; @@ -40,10 +39,6 @@ export function NoAvatarEmptyTitle(): JSX.Element { return ; } -NoAvatarEmptyTitle.story = { - name: 'No avatar, empty title', -}; - export function AvatarAndTitle(): JSX.Element { return ( ); } - -HasError.story = { - name: 'Has error', -}; diff --git a/ts/components/conversation/conversation-details/GroupLinkManagement.stories.tsx b/ts/components/conversation/conversation-details/GroupLinkManagement.stories.tsx index 6c34590e23..501a99aa2e 100644 --- a/ts/components/conversation/conversation-details/GroupLinkManagement.stories.tsx +++ b/ts/components/conversation/conversation-details/GroupLinkManagement.stories.tsx @@ -2,9 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; import type { PropsType } from './GroupLinkManagement'; @@ -17,7 +16,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/GroupLinkManagement', -}; +} satisfies Meta; const AccessControlEnum = Proto.AccessControl.AccessRequired; @@ -61,10 +60,6 @@ export function OffAdmin(): JSX.Element { return ; } -OffAdmin.story = { - name: 'Off (Admin)', -}; - export function OnAdmin(): JSX.Element { const props = createProps( getConversation('https://signal.group/1', AccessControlEnum.ANY), @@ -74,10 +69,6 @@ export function OnAdmin(): JSX.Element { return ; } -OnAdmin.story = { - name: 'On (Admin)', -}; - export function OnAdminAdminApprovalNeeded(): JSX.Element { const props = createProps( getConversation('https://signal.group/1', AccessControlEnum.ADMINISTRATOR), @@ -87,10 +78,6 @@ export function OnAdminAdminApprovalNeeded(): JSX.Element { return ; } -OnAdminAdminApprovalNeeded.story = { - name: 'On (Admin + Admin Approval Needed)', -}; - export function OnNonAdmin(): JSX.Element { const props = createProps( getConversation('https://signal.group/1', AccessControlEnum.ANY) @@ -99,16 +86,8 @@ export function OnNonAdmin(): JSX.Element { return ; } -OnNonAdmin.story = { - name: 'On (Non-admin)', -}; - export function OffNonAdminUserCannotGetHere(): JSX.Element { const props = createProps(undefined, false); return ; } - -OffNonAdminUserCannotGetHere.story = { - name: 'Off (Non-admin) - user cannot get here', -}; diff --git a/ts/components/conversation/conversation-details/GroupV2Permissions.stories.tsx b/ts/components/conversation/conversation-details/GroupV2Permissions.stories.tsx index 60ea837f94..63c23f907c 100644 --- a/ts/components/conversation/conversation-details/GroupV2Permissions.stories.tsx +++ b/ts/components/conversation/conversation-details/GroupV2Permissions.stories.tsx @@ -2,9 +2,8 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; import type { PropsType } from './GroupV2Permissions'; @@ -16,7 +15,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/GroupV2Permissions', -}; +} satisfies Meta; const conversation: ConversationType = getDefaultConversation({ id: '', @@ -58,10 +57,6 @@ export function NotAdmin(): JSX.Element { ); } -NotAdmin.story = { - name: 'Not admin', -}; - export function AdminButNotAnnouncementReady(): JSX.Element { return ( ); } - -AdminNotAnnouncementReadyButItWasOn.story = { - name: 'Admin, not announcement ready, but it was on', -}; diff --git a/ts/components/conversation/conversation-details/PanelRow.stories.tsx b/ts/components/conversation/conversation-details/PanelRow.stories.tsx index f13e203ba6..c65e2bfc7e 100644 --- a/ts/components/conversation/conversation-details/PanelRow.stories.tsx +++ b/ts/components/conversation/conversation-details/PanelRow.stories.tsx @@ -2,74 +2,66 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; -import { boolean, text } from '@storybook/addon-knobs'; - -import { ConversationDetailsIcon, IconType } from './ConversationDetailsIcon'; +import type { Meta } from '@storybook/react'; import type { Props } from './PanelRow'; import { PanelRow } from './PanelRow'; +import { ConversationDetailsIcon, IconType } from './ConversationDetailsIcon'; export default { title: 'Components/Conversation/ConversationDetails/PanelRow', -}; - -const createProps = (overrideProps: Partial = {}): Props => ({ - icon: boolean('with icon', overrideProps.icon !== undefined) ? ( - - ) : null, - label: text('label', (overrideProps.label as string) || ''), - info: text('info', overrideProps.info || ''), - right: text('right', (overrideProps.right as string) || ''), - actions: boolean('with action', overrideProps.actions !== undefined) ? ( - - ) : null, - onClick: boolean('clickable', overrideProps.onClick !== undefined) - ? overrideProps.onClick || action('onClick') - : undefined, -}); - -export function Basic(): JSX.Element { - const props = createProps({ - label: 'this is a panel row', - }); - - return ; -} - -export function Simple(): JSX.Element { - const props = createProps({ - label: 'this is a panel row', - icon: 'with icon', - right: 'side text', - }); - - return ; -} - -export function Full(): JSX.Element { - const props = createProps({ - label: 'this is a panel row', - icon: 'with icon', - info: 'this is some info that exists below the main label', - right: 'side text', - actions: 'with action', - }); - - return ; -} - -export function Button(): JSX.Element { - const props = createProps({ - label: 'this is a panel row', - icon: 'with icon', - right: 'side text', + argTypes: {}, + args: { + icon: , + label: '', + info: '', + right: '', + actions: ( + + ), onClick: action('onClick'), - }); + }, +} satisfies Meta; - return ; +export function Basic(args: Props): JSX.Element { + return ; +} + +export function Simple(args: Props): JSX.Element { + return ( + + ); +} + +export function Full(args: Props): JSX.Element { + return ( + + ); +} + +export function Button(args: Props): JSX.Element { + return ( + + ); } diff --git a/ts/components/conversation/conversation-details/PanelSection.stories.tsx b/ts/components/conversation/conversation-details/PanelSection.stories.tsx index 437af8106a..eda85a6dbc 100644 --- a/ts/components/conversation/conversation-details/PanelSection.stories.tsx +++ b/ts/components/conversation/conversation-details/PanelSection.stories.tsx @@ -2,65 +2,46 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; -import { boolean, text } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import type { Props } from './PanelSection'; import { PanelSection } from './PanelSection'; import { PanelRow } from './PanelRow'; export default { title: 'Components/Conversation/ConversationDetails/PanelSection', -}; + argTypes: {}, + args: { + title: 'this is a panel row', + centerTitle: false, + actions: null, + }, +} satisfies Meta; -const createProps = (overrideProps: Partial = {}): Props => ({ - title: text('label', overrideProps.title || ''), - centerTitle: boolean('centerTitle', overrideProps.centerTitle || false), - actions: boolean('with action', overrideProps.actions !== undefined) ? ( - - ) : null, -}); - -export function Basic(): JSX.Element { - const props = createProps({ - title: 'panel section header', - }); - - return ; +export function Basic(args: Props): JSX.Element { + return ; } -export function Centered(): JSX.Element { - const props = createProps({ - title: 'this is a panel row', - centerTitle: true, - }); - - return ; +export function Centered(args: Props): JSX.Element { + return ; } -export function WithActions(): JSX.Element { - const props = createProps({ - title: 'this is a panel row', - actions: ( - - ), - }); - - return ; -} - -export function WithContent(): JSX.Element { - const props = createProps({ - title: 'this is a panel row', - }); - +export function WithActions(args: Props): JSX.Element { return ( - + + action + + } + /> + ); +} + +export function WithContent(args: Props): JSX.Element { + return ( + diff --git a/ts/components/conversation/conversation-details/PendingInvites.stories.tsx b/ts/components/conversation/conversation-details/PendingInvites.stories.tsx index 6cf8d1c4be..069b7a91b0 100644 --- a/ts/components/conversation/conversation-details/PendingInvites.stories.tsx +++ b/ts/components/conversation/conversation-details/PendingInvites.stories.tsx @@ -3,10 +3,9 @@ import * as React from 'react'; import { times } from 'lodash'; - import { action } from '@storybook/addon-actions'; - -import { UUID } from '../../../types/UUID'; +import type { Meta } from '@storybook/react'; +import { generateAci } from '../../../types/ServiceId'; import { StorySendMode } from '../../../types/Stories'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; @@ -21,7 +20,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/ConversationDetails/PendingInvites', -}; +} satisfies Meta; const sortedGroupMembers = Array.from(Array(32)).map((_, i) => i === 0 @@ -45,7 +44,7 @@ const conversation: ConversationType = { storySendMode: StorySendMode.IfActive, }; -const OUR_UUID = UUID.generate().toString(); +const OUR_UUID = generateAci(); const useProps = (overrideProps: Partial = {}): PropsType => ({ approvePendingMembershipFromGroupV2: action( @@ -54,7 +53,7 @@ const useProps = (overrideProps: Partial = {}): PropsType => ({ conversation, getPreferredBadge: () => undefined, i18n, - ourUuid: OUR_UUID, + ourAci: OUR_UUID, pendingApprovalMemberships: times(5, () => ({ member: getDefaultConversation(), })), @@ -68,7 +67,7 @@ const useProps = (overrideProps: Partial = {}): PropsType => ({ ...times(8, () => ({ member: getDefaultConversation(), metadata: { - addedByUserId: UUID.generate().toString(), + addedByUserId: generateAci(), }, })), ], @@ -90,7 +89,3 @@ export function WithBadges(): JSX.Element { return ; } - -WithBadges.story = { - name: 'With badges', -}; diff --git a/ts/components/conversation/conversation-details/PendingInvites.tsx b/ts/components/conversation/conversation-details/PendingInvites.tsx index 24bc2a3ad2..6720565529 100644 --- a/ts/components/conversation/conversation-details/PendingInvites.tsx +++ b/ts/components/conversation/conversation-details/PendingInvites.tsx @@ -7,7 +7,7 @@ import _ from 'lodash'; import type { ConversationType } from '../../../state/ducks/conversations'; import type { LocalizerType, ThemeType } from '../../../types/Util'; import type { PreferredBadgeSelectorType } from '../../../state/selectors/badges'; -import type { UUIDStringType } from '../../../types/UUID'; +import type { AciString } from '../../../types/ServiceId'; import { Avatar, AvatarSize } from '../../Avatar'; import { ConfirmationDialog } from '../../ConfirmationDialog'; import { PanelSection } from './PanelSection'; @@ -21,7 +21,7 @@ export type PropsDataType = { readonly conversation?: ConversationType; readonly getPreferredBadge: PreferredBadgeSelectorType; readonly i18n: LocalizerType; - readonly ourUuid: UUIDStringType; + readonly ourAci: AciString; readonly pendingApprovalMemberships: ReadonlyArray; readonly pendingMemberships: ReadonlyArray; readonly theme: ThemeType; @@ -42,7 +42,7 @@ export type PropsType = PropsDataType & PropsActionType; export type GroupV2PendingMembership = { metadata: { - addedByUserId?: UUIDStringType; + addedByUserId?: AciString; }; member: ConversationType; }; @@ -72,16 +72,14 @@ export function PendingInvites({ conversation, getPreferredBadge, i18n, - ourUuid, + ourAci, pendingMemberships, pendingApprovalMemberships, revokePendingMembershipsFromGroupV2, theme, }: PropsType): JSX.Element { - if (!conversation || !ourUuid) { - throw new Error( - 'PendingInvites rendered without a conversation or ourUuid' - ); + if (!conversation || !ourAci) { + throw new Error('PendingInvites rendered without a conversation or ourAci'); } const [stagedMemberships, setStagedMemberships] = @@ -126,7 +124,7 @@ export function PendingInvites({ i18n={i18n} members={conversation.sortedGroupMembers || []} memberships={pendingMemberships} - ourUuid={ourUuid} + ourAci={ourAci} setStagedMemberships={setStagedMemberships} theme={theme} /> @@ -144,7 +142,7 @@ export function PendingInvites({ i18n={i18n} members={conversation.sortedGroupMembers || []} onClose={() => setStagedMemberships(null)} - ourUuid={ourUuid} + ourAci={ourAci} revokePendingMembershipsFromGroupV2={ revokePendingMembershipsFromGroupV2 } @@ -161,7 +159,7 @@ function MembershipActionConfirmation({ i18n, members, onClose, - ourUuid, + ourAci, revokePendingMembershipsFromGroupV2, stagedMemberships, }: { @@ -173,7 +171,7 @@ function MembershipActionConfirmation({ i18n: LocalizerType; members: ReadonlyArray; onClose: () => void; - ourUuid: string; + ourAci: AciString; revokePendingMembershipsFromGroupV2: ( conversationId: string, memberIds: ReadonlyArray @@ -234,7 +232,7 @@ function MembershipActionConfirmation({ conversation, i18n, members, - ourUuid, + ourAci, stagedMemberships, })} @@ -245,13 +243,13 @@ function getConfirmationMessage({ conversation, i18n, members, - ourUuid, + ourAci, stagedMemberships, }: Readonly<{ conversation: ConversationType; i18n: LocalizerType; members: ReadonlyArray; - ourUuid: string; + ourAci: AciString; stagedMemberships: ReadonlyArray; }>): string { if (!stagedMemberships || !stagedMemberships.length) { @@ -285,7 +283,7 @@ function getConfirmationMessage({ const firstPendingMembership = firstMembership as GroupV2PendingMembership; // Pending invite - const invitedByUs = firstPendingMembership.metadata.addedByUserId === ourUuid; + const invitedByUs = firstPendingMembership.metadata.addedByUserId === ourAci; if (invitedByUs) { return i18n('icu:PendingInvites--revoke-for', { @@ -294,7 +292,8 @@ function getConfirmationMessage({ } const inviter = members.find( - ({ uuid }) => uuid === firstPendingMembership.metadata.addedByUserId + ({ serviceId }) => + serviceId === firstPendingMembership.metadata.addedByUserId ); if (inviter === undefined) { @@ -391,7 +390,7 @@ function MembersPendingProfileKey({ i18n, members, memberships, - ourUuid, + ourAci, setStagedMemberships, getPreferredBadge, theme, @@ -401,7 +400,7 @@ function MembersPendingProfileKey({ i18n: LocalizerType; members: ReadonlyArray; memberships: ReadonlyArray; - ourUuid: string; + ourAci: AciString; setStagedMemberships: (stagedMembership: Array) => void; theme: ThemeType; }>) { @@ -410,17 +409,20 @@ function MembersPendingProfileKey({ membership => membership.metadata.addedByUserId ); - const { [ourUuid]: ourPendingMemberships, ...otherPendingMembershipGroups } = + const { [ourAci]: ourPendingMemberships, ...otherPendingMembershipGroups } = groupedPendingMemberships; const otherPendingMemberships = Object.keys(otherPendingMembershipGroups) - .map(id => members.find(member => member.uuid === id)) + .map(id => members.find(member => member.serviceId === id)) .filter((member): member is ConversationType => member !== undefined) .map(member => { - assertDev(member.uuid, 'We just verified that member has uuid above'); + assertDev( + member.serviceId, + 'We just verified that member has serviceId above' + ); return { member, - pendingMemberships: otherPendingMembershipGroups[member.uuid], + pendingMemberships: otherPendingMembershipGroups[member.serviceId], }; }); diff --git a/ts/components/conversation/media-gallery/AttachmentSection.stories.tsx b/ts/components/conversation/media-gallery/AttachmentSection.stories.tsx index 5d30e734cd..f69a850f1c 100644 --- a/ts/components/conversation/media-gallery/AttachmentSection.stories.tsx +++ b/ts/components/conversation/media-gallery/AttachmentSection.stories.tsx @@ -4,122 +4,45 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import * as React from 'react'; -import { select, text } from '@storybook/addon-knobs'; -import { random, range, sample, sortBy } from 'lodash'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; -import type { MIMEType } from '../../../types/MIME'; -import type { MediaItemType } from '../../../types/MediaItem'; - import type { Props } from './AttachmentSection'; import { AttachmentSection } from './AttachmentSection'; +import { createRandomDocuments, createRandomMedia, days } from './utils/mocks'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/MediaGallery/AttachmentSection', -}; - -export const now = Date.now(); -const DAY_MS = 24 * 60 * 60 * 1000; -export const days = (n: number) => n * DAY_MS; -const tokens = ['foo', 'bar', 'baz', 'qux', 'quux']; - -const contentTypes = { - gif: 'image/gif', - jpg: 'image/jpeg', - png: 'image/png', - mp4: 'video/mp4', - docx: 'application/text', - pdf: 'application/pdf', - txt: 'application/text', -} as unknown as Record; - -const createRandomFile = ( - startTime: number, - timeWindow: number, - fileExtension: string -): MediaItemType => { - const contentType = contentTypes[fileExtension]; - const fileName = `${sample(tokens)}${sample(tokens)}.${fileExtension}`; - - return { - contentType, - message: { - conversationId: '123', - id: random(now).toString(), - received_at: Math.floor(Math.random() * 10), - received_at_ms: random(startTime, startTime + timeWindow), - attachments: [], - sent_at: Date.now(), + component: AttachmentSection, + argTypes: { + header: { control: { type: 'text' } }, + type: { + control: { + type: 'select', + options: ['media', 'documents'], + }, }, - attachment: { - url: '', - fileName, - size: random(1000, 1000 * 1000 * 50), - contentType, - }, - index: 0, - thumbnailObjectUrl: `https://placekitten.com/${random(50, 150)}/${random( - 50, - 150 - )}`, - }; -}; + }, + args: { + i18n, + header: 'Today', + type: 'media', + mediaItems: [], + onItemClick: action('onItemClick'), + }, +} satisfies Meta; -const createRandomFiles = ( - startTime: number, - timeWindow: number, - fileExtensions: Array -) => - range(random(5, 10)).map(() => - createRandomFile(startTime, timeWindow, sample(fileExtensions) as string) +export function Documents(args: Props) { + const mediaItems = createRandomDocuments(Date.now(), days(1)); + return ( + ); - -export const createRandomDocuments = (startTime: number, timeWindow: number) => - createRandomFiles(startTime, timeWindow, ['docx', 'pdf', 'txt']); - -export const createRandomMedia = (startTime: number, timeWindow: number) => - createRandomFiles(startTime, timeWindow, ['mp4', 'jpg', 'png', 'gif']); - -export const createPreparedMediaItems = ( - fn: typeof createRandomDocuments | typeof createRandomMedia -) => - sortBy( - [ - ...fn(now, days(1)), - ...fn(now - days(1), days(1)), - ...fn(now - days(3), days(3)), - ...fn(now - days(30), days(15)), - ...fn(now - days(365), days(300)), - ], - (item: MediaItemType) => -item.message.received_at - ); - -const createProps = (overrideProps: Partial = {}): Props => ({ - i18n, - header: text('header', 'Today'), - type: select( - 'type', - { media: 'media', documents: 'documents' }, - overrideProps.type || 'media' - ), - mediaItems: overrideProps.mediaItems || [], - onItemClick: action('onItemClick'), -}); - -export function Documents() { - const mediaItems = createRandomDocuments(now, days(1)); - const props = createProps({ mediaItems, type: 'documents' }); - - return ; } -export function Media() { - const mediaItems = createRandomMedia(now, days(1)); - const props = createProps({ mediaItems, type: 'media' }); - - return ; +export function Media(args: Props) { + const mediaItems = createRandomMedia(Date.now(), days(1)); + return ; } diff --git a/ts/components/conversation/media-gallery/AttachmentSection.tsx b/ts/components/conversation/media-gallery/AttachmentSection.tsx index b5f1810166..22c3de1c42 100644 --- a/ts/components/conversation/media-gallery/AttachmentSection.tsx +++ b/ts/components/conversation/media-gallery/AttachmentSection.tsx @@ -35,7 +35,7 @@ export function AttachmentSection({ const { message, index, attachment } = mediaItem; const onClick = () => { - onItemClick({ type, message, attachment }); + onItemClick({ type, message, attachment, index: mediaItem.index }); }; switch (type) { diff --git a/ts/components/conversation/media-gallery/DocumentListItem.stories.tsx b/ts/components/conversation/media-gallery/DocumentListItem.stories.tsx index 6e16b96dd0..46646c7807 100644 --- a/ts/components/conversation/media-gallery/DocumentListItem.stories.tsx +++ b/ts/components/conversation/media-gallery/DocumentListItem.stories.tsx @@ -2,25 +2,30 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { boolean, date, number, text } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { Props } from './DocumentListItem'; import { DocumentListItem } from './DocumentListItem'; export default { title: 'Components/Conversation/MediaGallery/DocumentListItem', -}; + argTypes: { + timestamp: { control: { type: 'date' } }, + fileName: { control: { type: 'text' } }, + fileSize: { control: { type: 'number' } }, + shouldShowSeparator: { control: { type: 'boolean' } }, + }, + args: { + timestamp: Date.now(), + fileName: 'meow.jpg', + fileSize: 1024 * 1000 * 2, + shouldShowSeparator: false, + onClick: action('onClick'), + }, +} satisfies Meta; -export function Single(): JSX.Element { - return ( - - ); +export function Single(args: Props): JSX.Element { + return ; } export function Multiple(): JSX.Element { diff --git a/ts/components/conversation/media-gallery/DocumentListItem.tsx b/ts/components/conversation/media-gallery/DocumentListItem.tsx index 77fdc07dc6..8975aebae9 100644 --- a/ts/components/conversation/media-gallery/DocumentListItem.tsx +++ b/ts/components/conversation/media-gallery/DocumentListItem.tsx @@ -7,7 +7,7 @@ import classNames from 'classnames'; import moment from 'moment'; import formatFileSize from 'filesize'; -type Props = { +export type Props = { // Required timestamp: number; diff --git a/ts/components/conversation/media-gallery/EmptyState.stories.tsx b/ts/components/conversation/media-gallery/EmptyState.stories.tsx index a02c7fe5dd..4031462679 100644 --- a/ts/components/conversation/media-gallery/EmptyState.stories.tsx +++ b/ts/components/conversation/media-gallery/EmptyState.stories.tsx @@ -2,13 +2,20 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { text } from '@storybook/addon-knobs'; +import type { Meta } from '@storybook/react'; +import type { Props } from './EmptyState'; import { EmptyState } from './EmptyState'; export default { title: 'Components/Conversation/MediaGallery/EmptyState', -}; + argTypes: { + label: { control: { type: 'text' } }, + }, + args: { + label: 'placeholder text', + }, +} satisfies Meta; -export function Default(): JSX.Element { - return ; +export function Default(args: Props): JSX.Element { + return ; } diff --git a/ts/components/conversation/media-gallery/EmptyState.tsx b/ts/components/conversation/media-gallery/EmptyState.tsx index 4415442c39..56829fb377 100644 --- a/ts/components/conversation/media-gallery/EmptyState.tsx +++ b/ts/components/conversation/media-gallery/EmptyState.tsx @@ -3,7 +3,7 @@ import React from 'react'; -type Props = { +export type Props = { label: string; }; diff --git a/ts/components/conversation/media-gallery/MediaGallery.stories.tsx b/ts/components/conversation/media-gallery/MediaGallery.stories.tsx index 1027f61a76..2c5c9182ee 100644 --- a/ts/components/conversation/media-gallery/MediaGallery.stories.tsx +++ b/ts/components/conversation/media-gallery/MediaGallery.stories.tsx @@ -3,25 +3,23 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; - +import type { Props } from './MediaGallery'; +import { MediaGallery } from './MediaGallery'; import { createPreparedMediaItems, createRandomDocuments, createRandomMedia, days, - now, -} from './AttachmentSection.stories'; -import type { Props } from './MediaGallery'; -import { MediaGallery } from './MediaGallery'; +} from './utils/mocks'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/MediaGallery/MediaGallery', -}; +} satisfies Meta; const createProps = (overrideProps: Partial = {}): Props => ({ conversationId: '123', @@ -34,7 +32,7 @@ const createProps = (overrideProps: Partial = {}): Props => ({ }); export function Populated(): JSX.Element { - const documents = createRandomDocuments(now, days(1)).slice(0, 1); + const documents = createRandomDocuments(Date.now(), days(1)).slice(0, 1); const media = createPreparedMediaItems(createRandomMedia); const props = createProps({ documents, media }); @@ -56,8 +54,8 @@ export function NoMedia(): JSX.Element { } export function OneEach(): JSX.Element { - const media = createRandomMedia(now, days(1)).slice(0, 1); - const documents = createRandomDocuments(now, days(1)).slice(0, 1); + const media = createRandomMedia(Date.now(), days(1)).slice(0, 1); + const documents = createRandomDocuments(Date.now(), days(1)).slice(0, 1); const props = createProps({ documents, media }); diff --git a/ts/components/conversation/media-gallery/MediaGallery.tsx b/ts/components/conversation/media-gallery/MediaGallery.tsx index 15bf8e3250..6b5565bf59 100644 --- a/ts/components/conversation/media-gallery/MediaGallery.tsx +++ b/ts/components/conversation/media-gallery/MediaGallery.tsx @@ -29,7 +29,7 @@ export type Props = { media: Array; saveAttachment: SaveAttachmentActionCreatorType; showLightboxWithMedia: ( - selectedAttachmentPath: string | undefined, + selectedIndex: number, media: Array ) => void; }; @@ -106,7 +106,7 @@ function MediaSection({ } case 'media': { - showLightboxWithMedia(event.attachment.path, media); + showLightboxWithMedia(event.index, media); break; } diff --git a/ts/components/conversation/media-gallery/MediaGridItem.stories.tsx b/ts/components/conversation/media-gallery/MediaGridItem.stories.tsx index 7f16220442..10672f0bfc 100644 --- a/ts/components/conversation/media-gallery/MediaGridItem.stories.tsx +++ b/ts/components/conversation/media-gallery/MediaGridItem.stories.tsx @@ -3,13 +3,12 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../../util/setupI18n'; import enMessages from '../../../../_locales/en/messages.json'; import type { MediaItemType } from '../../../types/MediaItem'; import type { AttachmentType } from '../../../types/Attachment'; import { stringToMIMEType } from '../../../types/MIME'; - import type { Props } from './MediaGridItem'; import { MediaGridItem } from './MediaGridItem'; @@ -17,7 +16,7 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Conversation/MediaGallery/MediaGridItem', -}; +} satisfies Meta; const createProps = ( overrideProps: Partial & { mediaItem: MediaItemType } @@ -131,7 +130,3 @@ export function OtherContentType(): JSX.Element { return ; } - -OtherContentType.story = { - name: 'Other ContentType', -}; diff --git a/ts/components/conversation/media-gallery/types/ItemClickEvent.ts b/ts/components/conversation/media-gallery/types/ItemClickEvent.ts index 960b4502d6..553d3f2290 100644 --- a/ts/components/conversation/media-gallery/types/ItemClickEvent.ts +++ b/ts/components/conversation/media-gallery/types/ItemClickEvent.ts @@ -7,5 +7,6 @@ import type { AttachmentType } from '../../../../types/Attachment'; export type ItemClickEvent = { message: Pick; attachment: AttachmentType; + index: number; type: 'media' | 'documents'; }; diff --git a/ts/components/conversation/media-gallery/utils/mocks.ts b/ts/components/conversation/media-gallery/utils/mocks.ts new file mode 100644 index 0000000000..4894de4ad8 --- /dev/null +++ b/ts/components/conversation/media-gallery/utils/mocks.ts @@ -0,0 +1,91 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { random, range, sample, sortBy } from 'lodash'; +import type { MIMEType } from '../../../../types/MIME'; +import type { MediaItemType } from '../../../../types/MediaItem'; + +const DAY_MS = 24 * 60 * 60 * 1000; +export const days = (n: number): number => n * DAY_MS; +const tokens = ['foo', 'bar', 'baz', 'qux', 'quux']; + +const contentTypes = { + gif: 'image/gif', + jpg: 'image/jpeg', + png: 'image/png', + mp4: 'video/mp4', + docx: 'application/text', + pdf: 'application/pdf', + txt: 'application/text', +} as unknown as Record; + +function createRandomFile( + startTime: number, + timeWindow: number, + fileExtension: string +): MediaItemType { + const contentType = contentTypes[fileExtension]; + const fileName = `${sample(tokens)}${sample(tokens)}.${fileExtension}`; + + return { + contentType, + message: { + conversationId: '123', + id: random(Date.now()).toString(), + received_at: Math.floor(Math.random() * 10), + received_at_ms: random(startTime, startTime + timeWindow), + attachments: [], + sent_at: Date.now(), + }, + attachment: { + url: '', + fileName, + size: random(1000, 1000 * 1000 * 50), + contentType, + }, + index: 0, + thumbnailObjectUrl: `https://placekitten.com/${random(50, 150)}/${random( + 50, + 150 + )}`, + }; +} + +function createRandomFiles( + startTime: number, + timeWindow: number, + fileExtensions: Array +): Array { + return range(random(5, 10)).map(() => + createRandomFile(startTime, timeWindow, sample(fileExtensions) as string) + ); +} +export function createRandomDocuments( + startTime: number, + timeWindow: number +): Array { + return createRandomFiles(startTime, timeWindow, ['docx', 'pdf', 'txt']); +} + +export function createRandomMedia( + startTime: number, + timeWindow: number +): Array { + return createRandomFiles(startTime, timeWindow, ['mp4', 'jpg', 'png', 'gif']); +} + +export function createPreparedMediaItems( + fn: typeof createRandomDocuments | typeof createRandomMedia +): Array { + const now = Date.now(); + return sortBy( + [ + ...fn(now, days(1)), + ...fn(now - days(1), days(1)), + ...fn(now - days(3), days(3)), + ...fn(now - days(30), days(15)), + ...fn(now - days(365), days(300)), + ], + (item: MediaItemType) => -item.message.received_at + ); +} diff --git a/ts/components/conversationList/BaseConversationListItem.tsx b/ts/components/conversationList/BaseConversationListItem.tsx index 62bc87b00c..77f619a12a 100644 --- a/ts/components/conversationList/BaseConversationListItem.tsx +++ b/ts/components/conversationList/BaseConversationListItem.tsx @@ -5,6 +5,7 @@ import type { ReactNode, FunctionComponent } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import classNames from 'classnames'; import { isBoolean, isNumber } from 'lodash'; +import { v4 as generateUuid } from 'uuid'; import { Avatar, AvatarSize } from '../Avatar'; import type { BadgeType } from '../../badges/types'; @@ -16,7 +17,6 @@ import { Spinner } from '../Spinner'; import { Time } from '../Time'; import { formatDateTimeShort } from '../../util/timestamp'; import * as durations from '../../util/durations'; -import { UUID } from '../../types/UUID'; const BASE_CLASS_NAME = 'module-conversation-list__item--contact-or-conversation'; @@ -68,7 +68,7 @@ type PropsType = { | 'sharedGroupNames' | 'title' | 'unblurredAvatarPath' - | 'uuid' + | 'serviceId' > & ( | { badge?: undefined; theme?: ThemeType } @@ -109,12 +109,12 @@ export const BaseConversationListItem: FunctionComponent = unblurredAvatarPath, unreadCount, unreadMentionsCount, - uuid, + serviceId, } = props; const identifier = id ? cleanId(id) : undefined; - const htmlId = useMemo(() => UUID.generate().toString(), []); - const testId = overrideTestId || groupId || uuid; + const htmlId = useMemo(() => generateUuid(), []); + const testId = overrideTestId || groupId || serviceId; const isUnread = isConversationUnread({ markedUnread, unreadCount }); const isAvatarNoteToSelf = isBoolean(isNoteToSelf) @@ -257,7 +257,7 @@ export const BaseConversationListItem: FunctionComponent = className={classNames( commonClassNames, `${BASE_CLASS_NAME}--is-checkbox`, - { [`${BASE_CLASS_NAME}--is-checkbox--disabled`]: disabled } + { [`${BASE_CLASS_NAME}--disabled`]: disabled } )} data-id={identifier} data-testid={testId} diff --git a/ts/components/conversationList/ContactCheckbox.tsx b/ts/components/conversationList/ContactCheckbox.tsx index b3b70305ad..9b42fad43d 100644 --- a/ts/components/conversationList/ContactCheckbox.tsx +++ b/ts/components/conversationList/ContactCheckbox.tsx @@ -38,7 +38,7 @@ export type PropsDataType = { | 'title' | 'type' | 'unblurredAvatarPath' - | 'uuid' + | 'serviceId' >; type PropsHousekeepingType = { diff --git a/ts/components/conversationList/ContactListItem.tsx b/ts/components/conversationList/ContactListItem.tsx index 4ce4f3a8ac..9702c83c43 100644 --- a/ts/components/conversationList/ContactListItem.tsx +++ b/ts/components/conversationList/ContactListItem.tsx @@ -39,7 +39,7 @@ export type ContactListItemConversationType = Pick< | 'unblurredAvatarPath' | 'username' | 'e164' - | 'uuid' + | 'serviceId' >; type PropsDataType = ContactListItemConversationType & { @@ -85,7 +85,7 @@ export const ContactListItem: FunctionComponent = React.memo( title, type, unblurredAvatarPath, - uuid, + serviceId, }) { const [isConfirmingBlocking, setConfirmingBlocking] = useState(false); const [isConfirmingRemoving, setConfirmingRemoving] = useState(false); @@ -149,7 +149,7 @@ export const ContactListItem: FunctionComponent = React.memo( /> ) : ( diff --git a/ts/components/conversationList/ConversationListItem.tsx b/ts/components/conversationList/ConversationListItem.tsx index d0f97d229c..4bfbf2194f 100644 --- a/ts/components/conversationList/ConversationListItem.tsx +++ b/ts/components/conversationList/ConversationListItem.tsx @@ -60,11 +60,11 @@ export type PropsData = Pick< | 'shouldShowDraft' | 'title' | 'type' - | 'typingContactId' + | 'typingContactIdTimestamps' | 'unblurredAvatarPath' | 'unreadCount' | 'unreadMentionsCount' - | 'uuid' + | 'serviceId' > & { badge?: BadgeType; }; @@ -104,13 +104,15 @@ export const ConversationListItem: FunctionComponent = React.memo( theme, title, type, - typingContactId, + typingContactIdTimestamps, unblurredAvatarPath, unreadCount, unreadMentionsCount, - uuid, + serviceId, }) { const isMuted = Boolean(muteExpiresAt && Date.now() < muteExpiresAt); + const isSomeoneTyping = + Object.keys(typingContactIdTimestamps ?? {}).length > 0; const headerName = ( <> {isMe ? ( @@ -122,7 +124,7 @@ export const ConversationListItem: FunctionComponent = React.memo( ) : ( )} @@ -139,7 +141,7 @@ export const ConversationListItem: FunctionComponent = React.memo( {i18n('icu:ConversationListItem--message-request')} ); - } else if (typingContactId) { + } else if (isSomeoneTyping) { messageText = ; } else if (shouldShowDraft && draftPreview) { messageText = ( @@ -221,7 +223,7 @@ export const ConversationListItem: FunctionComponent = React.memo( unreadCount={unreadCount} unreadMentionsCount={unreadMentionsCount} unblurredAvatarPath={unblurredAvatarPath} - uuid={uuid} + serviceId={serviceId} /> ); } diff --git a/ts/components/conversationList/GroupListItem.tsx b/ts/components/conversationList/GroupListItem.tsx index 77858b6f0d..69dd6d661e 100644 --- a/ts/components/conversationList/GroupListItem.tsx +++ b/ts/components/conversationList/GroupListItem.tsx @@ -4,7 +4,7 @@ import React from 'react'; import type { ConversationType } from '../../state/ducks/conversations'; import type { LocalizerType } from '../../types/Util'; -import type { UUIDStringType } from '../../types/UUID'; +import type { AciString } from '../../types/ServiceId'; import { Avatar, AvatarSize } from '../Avatar'; import { ListTile } from '../ListTile'; import { UserText } from '../UserText'; @@ -21,7 +21,7 @@ export type GroupListItemConversationType = Pick< disabledReason: DisabledReason | undefined; membersCount: number; memberships: ReadonlyArray<{ - uuid: UUIDStringType; + aci: AciString; isAdmin: boolean; }>; }; diff --git a/ts/components/conversationList/MessageSearchResult.stories.tsx b/ts/components/conversationList/MessageSearchResult.stories.tsx index eded368b64..d56e3d5868 100644 --- a/ts/components/conversationList/MessageSearchResult.stories.tsx +++ b/ts/components/conversationList/MessageSearchResult.stories.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; import { StorybookThemeContext } from '../../../.storybook/StorybookThemeContext'; @@ -13,12 +13,17 @@ import type { PropsType } from './MessageSearchResult'; import { MessageSearchResult } from './MessageSearchResult'; import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation'; import { BodyRange } from '../../types/BodyRange'; +import { generateAci } from '../../types/ServiceId'; + +const SERVICE_ID_1 = generateAci(); +const SERVICE_ID_2 = generateAci(); +const SERVICE_ID_3 = generateAci(); const i18n = setupI18n('en', enMessages); export default { title: 'Components/MessageSearchResult', -}; +} satisfies Meta; const someone = getDefaultConversation({ title: 'Some Person', @@ -80,10 +85,6 @@ export function SenderHasABadge(): JSX.Element { return ; } -SenderHasABadge.story = { - name: 'Sender has a badge', -}; - export function Selected(): JSX.Element { const props = useProps({ from: someone, @@ -113,10 +114,6 @@ export function SearchingInConversation(): JSX.Element { return ; } -SearchingInConversation.story = { - name: 'Searching in Conversation', -}; - export function FromYouToYourself(): JSX.Element { const props = useProps({ from: me, @@ -126,10 +123,6 @@ export function FromYouToYourself(): JSX.Element { return ; } -FromYouToYourself.story = { - name: 'From You to Yourself', -}; - export function FromYouToGroup(): JSX.Element { const props = useProps({ from: me, @@ -139,10 +132,6 @@ export function FromYouToGroup(): JSX.Element { return ; } -FromYouToGroup.story = { - name: 'From You to Group', -}; - export function FromSomeoneToGroup(): JSX.Element { const props = useProps({ from: someone, @@ -152,10 +141,6 @@ export function FromSomeoneToGroup(): JSX.Element { return ; } -FromSomeoneToGroup.story = { - name: 'From Someone to Group', -}; - export function LongSearchResult(): JSX.Element { const snippets = [ 'This is a really <>detail<>ed long line which will wrap and only be cut off after it gets to three lines. So maybe this will make it in as well?', @@ -188,24 +173,20 @@ export function EmptyShouldBeInvalid(): JSX.Element { return ; } -EmptyShouldBeInvalid.story = { - name: 'Empty (should be invalid)', -}; - export function Mention(): JSX.Element { const props = useProps({ body: 'moss banana twine sound lake zoo brain count vacuum work stairs try power forget hair dry diary years no results \uFFFC elephant sorry umbrella potato igloo kangaroo home Georgia bayonet vector orange forge diary zebra turtle rise front \uFFFC', bodyRanges: [ { length: 1, - mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8', + mentionAci: SERVICE_ID_3, replacementText: 'Shoe', conversationID: 'x', start: 113, }, { length: 1, - mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8', + mentionAci: SERVICE_ID_3, replacementText: 'Shoe', conversationID: 'x', start: 237, @@ -220,17 +201,13 @@ export function Mention(): JSX.Element { return ; } -Mention.story = { - name: '@mention', -}; - export function MentionRegexp(): JSX.Element { const props = useProps({ body: '\uFFFC This is a (long) /text/ ^$ that is ... specially **crafted** to (test) our regexp escaping mechanism! Making sure that the code we write works in all sorts of scenarios', bodyRanges: [ { length: 1, - mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8', + mentionAci: SERVICE_ID_3, replacementText: 'RegExp', conversationID: 'x', start: 0, @@ -245,17 +222,13 @@ export function MentionRegexp(): JSX.Element { return ; } -MentionRegexp.story = { - name: '@mention regexp', -}; - export function MentionNoMatches(): JSX.Element { const props = useProps({ body: '\uFFFC hello', bodyRanges: [ { length: 1, - mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8', + mentionAci: SERVICE_ID_3, replacementText: 'Neo', conversationID: 'x', start: 0, @@ -269,24 +242,20 @@ export function MentionNoMatches(): JSX.Element { return ; } -MentionNoMatches.story = { - name: '@mention no-matches', -}; - export const _MentionNoMatches = (): JSX.Element => { const props = useProps({ body: 'moss banana twine sound lake zoo brain count vacuum work stairs try power forget hair dry diary years no results \uFFFC elephant sorry umbrella potato igloo kangaroo home Georgia bayonet vector orange forge diary zebra turtle rise front \uFFFC', bodyRanges: [ { length: 1, - mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8', + mentionAci: SERVICE_ID_3, replacementText: 'Shoe', conversationID: 'x', start: 113, }, { length: 1, - mentionUuid: '7d007e95-771d-43ad-9191-eaa86c773cb8', + mentionAci: SERVICE_ID_3, replacementText: 'Shoe', conversationID: 'x', start: 237, @@ -301,24 +270,20 @@ export const _MentionNoMatches = (): JSX.Element => { return ; }; -_MentionNoMatches.story = { - name: '@mention no-matches', -}; - export function DoubleMention(): JSX.Element { const props = useProps({ body: 'Hey \uFFFC \uFFFC --- test! Two mentions!', bodyRanges: [ { length: 1, - mentionUuid: '9eb2eb65-992a-4909-a2a5-18c56bd7648f', + mentionAci: SERVICE_ID_2, replacementText: 'Alice', conversationID: 'x', start: 4, }, { length: 1, - mentionUuid: '755ec61b-1590-48da-b003-3e57b2b54448', + mentionAci: SERVICE_ID_1, replacementText: 'Bob', conversationID: 'x', start: 6, @@ -332,10 +297,6 @@ export function DoubleMention(): JSX.Element { return ; } -DoubleMention.story = { - name: 'Double @mention', -}; - export function WithFormatting(): JSX.Element { const props = useProps({ body: "We're playing with formatting in fun ways like you do!", diff --git a/ts/components/conversationList/PhoneNumberCheckbox.tsx b/ts/components/conversationList/PhoneNumberCheckbox.tsx index 9893cb0c18..4cb6666dd9 100644 --- a/ts/components/conversationList/PhoneNumberCheckbox.tsx +++ b/ts/components/conversationList/PhoneNumberCheckbox.tsx @@ -10,7 +10,7 @@ import { SPINNER_CLASS_NAME } from './BaseConversationListItem'; import type { ParsedE164Type } from '../../util/libphonenumberInstance'; import type { LocalizerType, ThemeType } from '../../types/Util'; import { AvatarColors } from '../../types/Colors'; -import type { LookupConversationWithoutUuidActionsType } from '../../util/lookupConversationWithoutUuid'; +import type { LookupConversationWithoutServiceIdActionsType } from '../../util/lookupConversationWithoutServiceId'; import { ListTile } from '../ListTile'; import { Avatar, AvatarSize } from '../Avatar'; import { Spinner } from '../Spinner'; @@ -26,7 +26,7 @@ type PropsHousekeepingType = { i18n: LocalizerType; theme: ThemeType; toggleConversationInChooseMembers: (conversationId: string) => void; -} & LookupConversationWithoutUuidActionsType; +} & LookupConversationWithoutServiceIdActionsType; type PropsType = PropsDataType & PropsHousekeepingType; @@ -36,7 +36,7 @@ export const PhoneNumberCheckbox: FunctionComponent = React.memo( isChecked, isFetching, i18n, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, toggleConversationInChooseMembers, @@ -52,7 +52,7 @@ export const PhoneNumberCheckbox: FunctionComponent = React.memo( return; } - const conversationId = await lookupConversationWithoutUuid({ + const conversationId = await lookupConversationWithoutServiceId({ showUserNotFoundModal, setIsFetchingUUID, @@ -67,7 +67,7 @@ export const PhoneNumberCheckbox: FunctionComponent = React.memo( }, [ isFetching, toggleConversationInChooseMembers, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, setIsModalVisible, diff --git a/ts/components/conversationList/StartNewConversation.tsx b/ts/components/conversationList/StartNewConversation.tsx index 80767e4df2..bca17ec7ad 100644 --- a/ts/components/conversationList/StartNewConversation.tsx +++ b/ts/components/conversationList/StartNewConversation.tsx @@ -12,7 +12,7 @@ import { Avatar, AvatarSize } from '../Avatar'; import { Spinner } from '../Spinner'; import type { ParsedE164Type } from '../../util/libphonenumberInstance'; -import type { LookupConversationWithoutUuidActionsType } from '../../util/lookupConversationWithoutUuid'; +import type { LookupConversationWithoutServiceIdActionsType } from '../../util/lookupConversationWithoutServiceId'; import type { LocalizerType } from '../../types/Util'; import type { ShowConversationType } from '../../state/ducks/conversations'; import { AvatarColors } from '../../types/Colors'; @@ -25,7 +25,7 @@ type PropsData = { type PropsHousekeeping = { i18n: LocalizerType; showConversation: ShowConversationType; -} & LookupConversationWithoutUuidActionsType; +} & LookupConversationWithoutServiceIdActionsType; export type Props = PropsData & PropsHousekeeping; @@ -34,7 +34,7 @@ export const StartNewConversation: FunctionComponent = React.memo( i18n, phoneNumber, isFetching, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, showConversation, @@ -49,7 +49,7 @@ export const StartNewConversation: FunctionComponent = React.memo( if (isFetching) { return; } - const conversationId = await lookupConversationWithoutUuid({ + const conversationId = await lookupConversationWithoutServiceId({ showUserNotFoundModal, setIsFetchingUUID, @@ -63,7 +63,7 @@ export const StartNewConversation: FunctionComponent = React.memo( } }, [ showConversation, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, setIsModalVisible, diff --git a/ts/components/conversationList/UsernameCheckbox.tsx b/ts/components/conversationList/UsernameCheckbox.tsx index 62c57256e1..b4e3453364 100644 --- a/ts/components/conversationList/UsernameCheckbox.tsx +++ b/ts/components/conversationList/UsernameCheckbox.tsx @@ -6,7 +6,7 @@ import type { FunctionComponent } from 'react'; import type { LocalizerType, ThemeType } from '../../types/Util'; import { AvatarColors } from '../../types/Colors'; -import type { LookupConversationWithoutUuidActionsType } from '../../util/lookupConversationWithoutUuid'; +import type { LookupConversationWithoutServiceIdActionsType } from '../../util/lookupConversationWithoutServiceId'; import { ListTile } from '../ListTile'; import { Avatar, AvatarSize } from '../Avatar'; import { Spinner } from '../Spinner'; @@ -22,7 +22,7 @@ type PropsHousekeepingType = { i18n: LocalizerType; theme: ThemeType; toggleConversationInChooseMembers: (conversationId: string) => void; -} & LookupConversationWithoutUuidActionsType; +} & LookupConversationWithoutServiceIdActionsType; type PropsType = PropsDataType & PropsHousekeepingType; @@ -32,7 +32,7 @@ export const UsernameCheckbox: FunctionComponent = React.memo( isChecked, isFetching, i18n, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, toggleConversationInChooseMembers, @@ -42,7 +42,7 @@ export const UsernameCheckbox: FunctionComponent = React.memo( return; } - const conversationId = await lookupConversationWithoutUuid({ + const conversationId = await lookupConversationWithoutServiceId({ showUserNotFoundModal, setIsFetchingUUID, @@ -56,7 +56,7 @@ export const UsernameCheckbox: FunctionComponent = React.memo( }, [ isFetching, toggleConversationInChooseMembers, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, showUserNotFoundModal, setIsFetchingUUID, username, diff --git a/ts/components/conversationList/UsernameSearchResultListItem.tsx b/ts/components/conversationList/UsernameSearchResultListItem.tsx index 979a55ed81..a18a479bdc 100644 --- a/ts/components/conversationList/UsernameSearchResultListItem.tsx +++ b/ts/components/conversationList/UsernameSearchResultListItem.tsx @@ -9,7 +9,7 @@ import { Avatar, AvatarSize } from '../Avatar'; import { Spinner } from '../Spinner'; import type { LocalizerType } from '../../types/Util'; -import type { LookupConversationWithoutUuidActionsType } from '../../util/lookupConversationWithoutUuid'; +import type { LookupConversationWithoutServiceIdActionsType } from '../../util/lookupConversationWithoutServiceId'; import type { ShowConversationType } from '../../state/ducks/conversations'; type PropsData = { @@ -20,14 +20,14 @@ type PropsData = { type PropsHousekeeping = { i18n: LocalizerType; showConversation: ShowConversationType; -} & LookupConversationWithoutUuidActionsType; +} & LookupConversationWithoutServiceIdActionsType; export type Props = PropsData & PropsHousekeeping; export function UsernameSearchResultListItem({ i18n, isFetchingUsername, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, username, showUserNotFoundModal, setIsFetchingUUID, @@ -37,7 +37,7 @@ export function UsernameSearchResultListItem({ if (isFetchingUsername) { return; } - const conversationId = await lookupConversationWithoutUuid({ + const conversationId = await lookupConversationWithoutServiceId({ showUserNotFoundModal, setIsFetchingUUID, @@ -50,7 +50,7 @@ export function UsernameSearchResultListItem({ } }, [ isFetchingUsername, - lookupConversationWithoutUuid, + lookupConversationWithoutServiceId, setIsFetchingUUID, showConversation, showUserNotFoundModal, diff --git a/ts/components/emoji/Emoji.stories.tsx b/ts/components/emoji/Emoji.stories.tsx index c61d25229c..403f64ba37 100644 --- a/ts/components/emoji/Emoji.stories.tsx +++ b/ts/components/emoji/Emoji.stories.tsx @@ -2,63 +2,58 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { select, text } from '@storybook/addon-knobs'; +import type { Meta } from '@storybook/react'; import type { Props } from './Emoji'; import { Emoji, EmojiSizes } from './Emoji'; -export default { - title: 'Components/Emoji/Emoji', -}; - const tones = [0, 1, 2, 3, 4, 5]; -const createProps = (overrideProps: Partial = {}): Props => ({ - size: select( - 'size', - EmojiSizes.reduce((m, t) => ({ ...m, [t]: t }), {}), - overrideProps.size || 48 - ), - emoji: text('emoji', overrideProps.emoji || ''), - shortName: text('shortName', overrideProps.shortName || ''), - skinTone: select( - 'skinTone', - tones.reduce((m, t) => ({ ...m, [t]: t }), {}), - overrideProps.skinTone || 0 - ), -}); - -export function Sizes(): JSX.Element { - const props = createProps({ - shortName: 'grinning_face_with_star_eyes', - }); +export default { + title: 'Components/Emoji/Emoji', + argTypes: { + size: { control: { type: 'select' }, options: EmojiSizes }, + emoji: { control: { type: 'text' } }, + shortName: { control: { type: 'text' } }, + skinTone: { control: { type: 'select' }, options: tones }, + }, + args: { + size: 48, + emoji: '', + shortName: '', + skinTone: 0, + }, +} satisfies Meta; +export function Sizes(args: Props): JSX.Element { return ( <> {EmojiSizes.map(size => ( - + ))} ); } -export function SkinTones(): JSX.Element { - const props = createProps({ - shortName: 'raised_back_of_hand', - }); - +export function SkinTones(args: Props): JSX.Element { return ( <> {tones.map(skinTone => ( - + ))} ); } -export function FromEmoji(): JSX.Element { - const props = createProps({ - emoji: '😂', - }); - - return ; +export function FromEmoji(args: Props): JSX.Element { + return ; } diff --git a/ts/components/emoji/EmojiButton.stories.tsx b/ts/components/emoji/EmojiButton.stories.tsx index 7d656e5100..72a890262f 100644 --- a/ts/components/emoji/EmojiButton.stories.tsx +++ b/ts/components/emoji/EmojiButton.stories.tsx @@ -2,19 +2,18 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; - +import type { Props } from './EmojiButton'; import { EmojiButton } from './EmojiButton'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Emoji/EmojiButton', -}; +} satisfies Meta; export function Base(): JSX.Element { return ( diff --git a/ts/components/emoji/EmojiButton.tsx b/ts/components/emoji/EmojiButton.tsx index 9563aca17a..5407316c88 100644 --- a/ts/components/emoji/EmojiButton.tsx +++ b/ts/components/emoji/EmojiButton.tsx @@ -25,6 +25,7 @@ export type OwnProps = Readonly<{ emoji?: string; i18n: LocalizerType; onClose?: () => unknown; + onOpen?: () => unknown; emojiButtonApi?: MutableRefObject; variant?: EmojiButtonVariant; }>; @@ -32,7 +33,7 @@ export type OwnProps = Readonly<{ export type Props = OwnProps & Pick< EmojiPickerProps, - 'doSend' | 'onPickEmoji' | 'onSetSkinTone' | 'recentEmojis' | 'skinTone' + 'onPickEmoji' | 'onSetSkinTone' | 'recentEmojis' | 'skinTone' >; export type EmojiButtonAPI = Readonly<{ @@ -45,19 +46,28 @@ export const EmojiButton = React.memo(function EmojiButtonInner({ emoji, emojiButtonApi, i18n, - doSend, onClose, + onOpen, onPickEmoji, skinTone, onSetSkinTone, recentEmojis, variant = EmojiButtonVariant.Normal, }: Props) { + const isRTL = i18n.getLocaleDirection() === 'rtl'; + const [open, setOpen] = React.useState(false); const buttonRef = React.useRef(null); const popperRef = React.useRef(null); const refMerger = useRefMerger(); + React.useEffect(() => { + if (!open) { + return; + } + onOpen?.(); + }, [open, onOpen]); + const handleClickButton = React.useCallback(() => { if (open) { setOpen(false); @@ -155,7 +165,7 @@ export const EmojiButton = React.memo(function EmojiButtonInner({ {open ? (
- + {({ ref, style }) => ( ; export function Base(): JSX.Element { return ( @@ -88,7 +87,3 @@ export function WithSettingsButton(): JSX.Element { /> ); } - -WithSettingsButton.story = { - name: 'With settings button', -}; diff --git a/ts/components/emoji/EmojiPicker.tsx b/ts/components/emoji/EmojiPicker.tsx index 06db09668f..d198d7a00e 100644 --- a/ts/components/emoji/EmojiPicker.tsx +++ b/ts/components/emoji/EmojiPicker.tsx @@ -34,7 +34,6 @@ export type EmojiPickDataType = { export type OwnProps = { readonly i18n: LocalizerType; readonly onPickEmoji: (o: EmojiPickDataType) => unknown; - readonly doSend?: () => unknown; readonly skinTone?: number; readonly onSetSkinTone?: (tone: number) => unknown; readonly recentEmojis?: ReadonlyArray; @@ -71,7 +70,6 @@ export const EmojiPicker = React.memo( ( { i18n, - doSend, onPickEmoji, skinTone = 0, onSetSkinTone, @@ -82,6 +80,8 @@ export const EmojiPicker = React.memo( }: Props, ref ) => { + const isRTL = i18n.getLocaleDirection() === 'rtl'; + const [firstRecent] = React.useState(recentEmojis); const [selectedCategory, setSelectedCategory] = React.useState( categories[0] @@ -151,11 +151,7 @@ export const EmojiPicker = React.memo( const { shortName } = e.currentTarget.dataset; if ('key' in e) { if (e.key === 'Enter') { - if (doSend) { - doSend(); - e.stopPropagation(); - e.preventDefault(); - } else if (shortName) { + if (shortName) { onPickEmoji({ skinTone: selectedTone, shortName }); e.stopPropagation(); e.preventDefault(); @@ -167,7 +163,7 @@ export const EmojiPicker = React.memo( onPickEmoji({ skinTone: selectedTone, shortName }); } }, - [doSend, onPickEmoji, selectedTone] + [onPickEmoji, selectedTone] ); // Handle key presses, particularly Escape @@ -445,6 +441,8 @@ export const EmojiPicker = React.memo( height={height} columnCount={COL_COUNT} columnWidth={38} + // react-virtualized Grid default style has direction: 'ltr' + style={{ direction: isRTL ? 'rtl' : 'ltr' }} rowHeight={getRowHeight} rowCount={rowCount} cellRenderer={cellRenderer} diff --git a/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.stories.tsx b/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.stories.tsx index 72d46649dc..5faff62281 100644 --- a/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.stories.tsx +++ b/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.stories.tsx @@ -2,19 +2,18 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { useState } from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; - +import type { PropsType } from './InstallScreenChoosingDeviceNameStep'; import { InstallScreenChoosingDeviceNameStep } from './InstallScreenChoosingDeviceNameStep'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/InstallScreen/InstallScreenChoosingDeviceNameStep', -}; +} satisfies Meta; function Wrapper() { const [deviceName, setDeviceName] = useState('Default value'); diff --git a/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.tsx b/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.tsx index 7d5f99bcb7..09b48a7e9c 100644 --- a/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.tsx +++ b/ts/components/installScreen/InstallScreenChoosingDeviceNameStep.tsx @@ -16,7 +16,7 @@ import { InstallScreenSignalLogo } from './InstallScreenSignalLogo'; // DESKTOP-2844. export const MAX_DEVICE_NAME_LENGTH = 50; -type PropsType = { +export type PropsType = { deviceName: string; i18n: LocalizerType; onSubmit: () => void; diff --git a/ts/components/installScreen/InstallScreenErrorStep.stories.tsx b/ts/components/installScreen/InstallScreenErrorStep.stories.tsx index 5566229387..4cddc8307b 100644 --- a/ts/components/installScreen/InstallScreenErrorStep.stories.tsx +++ b/ts/components/installScreen/InstallScreenErrorStep.stories.tsx @@ -2,19 +2,18 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; - import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; - +import type { Props } from './InstallScreenErrorStep'; import { InstallScreenErrorStep, InstallError } from './InstallScreenErrorStep'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/InstallScreen/InstallScreenErrorStep', -}; +} satisfies Meta; const defaultProps = { i18n, @@ -29,26 +28,14 @@ export const _TooManyDevices = (): JSX.Element => ( /> ); -_TooManyDevices.story = { - name: 'Too many devices', -}; - export const _TooOld = (): JSX.Element => ( ); -_TooOld.story = { - name: 'Too old', -}; - export const __TooOld = (): JSX.Element => ( ); -__TooOld.story = { - name: 'Too old', -}; - export const _ConnectionFailed = (): JSX.Element => ( ( /> ); -_ConnectionFailed.story = { - name: 'Connection failed', -}; - export const _UnknownError = (): JSX.Element => ( ); - -_UnknownError.story = { - name: 'Unknown error', -}; diff --git a/ts/components/installScreen/InstallScreenErrorStep.tsx b/ts/components/installScreen/InstallScreenErrorStep.tsx index a4edcdac74..ff1c0184d4 100644 --- a/ts/components/installScreen/InstallScreenErrorStep.tsx +++ b/ts/components/installScreen/InstallScreenErrorStep.tsx @@ -19,17 +19,19 @@ export enum InstallError { QRCodeFailed, } +export type Props = Readonly<{ + error: InstallError; + i18n: LocalizerType; + quit: () => unknown; + tryAgain: () => unknown; +}>; + export function InstallScreenErrorStep({ error, i18n, quit, tryAgain, -}: Readonly<{ - error: InstallError; - i18n: LocalizerType; - quit: () => unknown; - tryAgain: () => unknown; -}>): ReactElement { +}: Props): ReactElement { let errorMessage: string; let buttonText = i18n('icu:installTryAgain'); let onClickButton = () => tryAgain(); diff --git a/ts/components/installScreen/InstallScreenLinkInProgress.stories.tsx b/ts/components/installScreen/InstallScreenLinkInProgress.stories.tsx index 56f94957a8..f42792ec27 100644 --- a/ts/components/installScreen/InstallScreenLinkInProgress.stories.tsx +++ b/ts/components/installScreen/InstallScreenLinkInProgress.stories.tsx @@ -2,17 +2,17 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; - +import type { Props } from './InstallScreenLinkInProgressStep'; import { InstallScreenLinkInProgressStep } from './InstallScreenLinkInProgressStep'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/InstallScreen/InstallScreenLinkInProgressStep', -}; +} satisfies Meta; export function Default(): JSX.Element { return ; diff --git a/ts/components/installScreen/InstallScreenLinkInProgressStep.tsx b/ts/components/installScreen/InstallScreenLinkInProgressStep.tsx index a56a5fff8e..ebf2c2e361 100644 --- a/ts/components/installScreen/InstallScreenLinkInProgressStep.tsx +++ b/ts/components/installScreen/InstallScreenLinkInProgressStep.tsx @@ -10,9 +10,9 @@ import { Spinner } from '../Spinner'; import { TitlebarDragArea } from '../TitlebarDragArea'; import { InstallScreenSignalLogo } from './InstallScreenSignalLogo'; -export function InstallScreenLinkInProgressStep({ - i18n, -}: Readonly<{ i18n: LocalizerType }>): ReactElement { +export type Props = Readonly<{ i18n: LocalizerType }>; + +export function InstallScreenLinkInProgressStep({ i18n }: Props): ReactElement { return (
diff --git a/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.stories.tsx b/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.stories.tsx index 3610be4d77..95edd97500 100644 --- a/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.stories.tsx +++ b/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.stories.tsx @@ -3,13 +3,13 @@ import React, { useEffect, useState } from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta, StoryFn } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import { DialogType } from '../../types/Dialogs'; import enMessages from '../../../_locales/en/messages.json'; - import type { Loadable } from '../../util/loadable'; import { LoadingState } from '../../util/loadable'; +import type { PropsType } from './InstallScreenQrCodeNotScannedStep'; import { InstallScreenQrCodeNotScannedStep } from './InstallScreenQrCodeNotScannedStep'; const i18n = setupI18n('en', enMessages); @@ -32,7 +32,7 @@ const DEFAULT_UPDATES = { export default { title: 'Components/InstallScreen/InstallScreenQrCodeNotScannedStep', argTypes: {}, -}; +} satisfies Meta; function Simulation({ finalResult }: { finalResult: Loadable }) { const [provisioningUrl, setProvisioningUrl] = useState>({ @@ -77,10 +77,6 @@ export function QrCodeLoading(): JSX.Element { ); } -QrCodeLoading.story = { - name: 'QR code loading', -}; - export function QrCodeFailedToLoad(): JSX.Element { return ( ; } -SimulatedLoading.story = { - name: 'Simulated loading', -}; - export function SimulatedFailure(): JSX.Element { return ( = + // eslint-disable-next-line react/function-component-definition + function WithUpdateKnobs({ + dialogType, + currentVersion, + }: { + dialogType: DialogType; + currentVersion: string; + }): JSX.Element { + return ( + + ); + }; -export function WithUpdateKnobs({ - dialogType, - currentVersion, -}: { - dialogType: DialogType; - currentVersion: string; -}): JSX.Element { - return ( - - ); -} - -WithUpdateKnobs.story = { - name: 'With Update Knobs', - argTypes: { - dialogType: { - control: { type: 'select' }, - defaultValue: DialogType.AutoUpdate, - options: Object.values(DialogType), - }, - currentVersion: { - control: { type: 'select' }, - defaultValue: 'v6.0.0', - options: ['v6.0.0', 'v6.1.0-beta.1'], - }, +WithUpdateKnobs.argTypes = { + dialogType: { + control: { type: 'select' }, + options: Object.values(DialogType), + }, + currentVersion: { + control: { type: 'select' }, + options: ['v6.0.0', 'v6.1.0-beta.1'], }, }; +WithUpdateKnobs.args = { + dialogType: DialogType.AutoUpdate, + currentVersion: 'v6.0.0', +}; diff --git a/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.tsx b/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.tsx index 011b561eec..ee60864839 100644 --- a/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.tsx +++ b/ts/components/installScreen/InstallScreenQrCodeNotScannedStep.tsx @@ -23,7 +23,7 @@ import { Environment, getEnvironment } from '../../environment'; // We can't always use destructuring assignment because of the complexity of this props // type. -type PropsType = Readonly<{ +export type PropsType = Readonly<{ i18n: LocalizerType; provisioningUrl: Loadable; hasExpired?: boolean; diff --git a/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx b/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx index c81d18309e..f539f49924 100644 --- a/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx +++ b/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx @@ -35,6 +35,7 @@ export type LeftPaneChooseGroupMembersPropsType = { isShowingRecommendedGroupSizeModal: boolean; isShowingMaximumGroupSizeModal: boolean; isUsernamesEnabled: boolean; + ourUsername: string | undefined; searchTerm: string; regionCode: string | undefined; selectedContacts: Array; @@ -74,6 +75,7 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper contact.username !== username); if (isUsernamesEnabled) { @@ -109,7 +112,11 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper contact.e164 === phoneNumber.e164); diff --git a/ts/components/stickers/StickerButton.stories.tsx b/ts/components/stickers/StickerButton.stories.tsx index 827680f321..b8c2ac50f5 100644 --- a/ts/components/stickers/StickerButton.stories.tsx +++ b/ts/components/stickers/StickerButton.stories.tsx @@ -1,11 +1,9 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { DecoratorFunction } from '@storybook/addons'; import * as React from 'react'; import { action } from '@storybook/addon-actions'; -import { boolean } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; import type { Props } from './StickerButton'; @@ -16,7 +14,7 @@ import { sticker2, tallSticker, wideSticker, -} from './StickerPicker.stories'; +} from './mocks'; const i18n = setupI18n('en', enMessages); @@ -36,8 +34,27 @@ export default { {storyFn()}
), - ] as Array>, -}; + ], + argTypes: { + showIntroduction: { control: { type: 'boolean' } }, + showPickerHint: { control: { type: 'boolean' } }, + }, + args: { + blessedPacks: [], + clearInstalledStickerPack: action('clearInstalledStickerPack'), + clearShowIntroduction: action('clearShowIntroduction'), + clearShowPickerHint: action('clearShowPickerHint'), + i18n, + installedPacks: [], + knownPacks: [], + onClickAddPack: action('onClickAddPack'), + onPickSticker: action('onPickSticker'), + receivedPacks: [], + recentStickers: [], + showIntroduction: false, + showPickerHint: false, + }, +} satisfies Meta; const receivedPacks = [ createPack({ id: 'received-pack-1', status: 'downloaded' }, sticker1), @@ -65,100 +82,61 @@ const knownPacks = [ createPack({ id: 'known-pack-2', status: 'known' }, sticker2), ]; -const createProps = (overrideProps: Partial = {}): Props => ({ - blessedPacks: overrideProps.blessedPacks || [], - clearInstalledStickerPack: action('clearInstalledStickerPack'), - clearShowIntroduction: action('clearShowIntroduction'), - clearShowPickerHint: action('clearShowPickerHint'), - i18n, - installedPack: overrideProps.installedPack, - installedPacks: overrideProps.installedPacks || [], - knownPacks: overrideProps.knownPacks || [], - onClickAddPack: action('onClickAddPack'), - onPickSticker: action('onPickSticker'), - receivedPacks: overrideProps.receivedPacks || [], - recentStickers: [], - showIntroduction: boolean( - 'showIntroduction', - overrideProps.showIntroduction || false - ), - showPickerHint: boolean('showPickerHint', false), -}); - -export function OnlyInstalled(): JSX.Element { - const props = createProps({ installedPacks }); - - return ; +export function OnlyInstalled(args: Props): JSX.Element { + return ; } -export function OnlyReceived(): JSX.Element { - const props = createProps({ receivedPacks }); - - return ; +export function OnlyReceived(args: Props): JSX.Element { + return ; } -export function OnlyKnown(): JSX.Element { - const props = createProps({ knownPacks }); - - return ; +export function OnlyKnown(args: Props): JSX.Element { + return ; } -export function OnlyBlessed(): JSX.Element { - const props = createProps({ blessedPacks }); - - return ; +export function OnlyBlessed(args: Props): JSX.Element { + return ; } -export function NoPacks(): JSX.Element { - const props = createProps(); - - return ; +export function NoPacks(args: Props): JSX.Element { + return ; } -export function InstalledPackTooltip(): JSX.Element { - const props = createProps({ - installedPacks, - installedPack: installedPacks[0], - }); - - return ; +export function InstalledPackTooltip(args: Props): JSX.Element { + return ( + + ); } -export function InstalledPackTooltipWide(): JSX.Element { +export function InstalledPackTooltipWide(args: Props): JSX.Element { const installedPack = createPack({ id: 'installed-pack-wide' }, wideSticker); - const props = createProps({ - installedPacks: [installedPack], - installedPack, - }); - - return ; + return ( + + ); } -InstalledPackTooltipWide.story = { - name: 'Installed Pack Tooltip (Wide)', -}; - -export function InstalledPackTooltipTall(): JSX.Element { +export function InstalledPackTooltipTall(args: Props): JSX.Element { const installedPack = createPack({ id: 'installed-pack-tall' }, tallSticker); - - const props = createProps({ - installedPacks: [installedPack], - installedPack, - }); - - return ; + return ( + + ); } -InstalledPackTooltipTall.story = { - name: 'Installed Pack Tooltip (Tall)', -}; - -export function NewInstallTooltip(): JSX.Element { - const props = createProps({ - installedPacks, - showIntroduction: true, - }); - - return ; +export function NewInstallTooltip(args: Props): JSX.Element { + return ( + + ); } diff --git a/ts/components/stickers/StickerManager.stories.tsx b/ts/components/stickers/StickerManager.stories.tsx index f0067314fe..cba68a01b1 100644 --- a/ts/components/stickers/StickerManager.stories.tsx +++ b/ts/components/stickers/StickerManager.stories.tsx @@ -3,18 +3,18 @@ import * as React from 'react'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; import type { Props } from './StickerManager'; import { StickerManager } from './StickerManager'; -import { createPack, sticker1, sticker2 } from './StickerPicker.stories'; +import { createPack, sticker1, sticker2 } from './mocks'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Stickers/StickerManager', -}; +} satisfies Meta; const receivedPacks = [ createPack({ id: 'received-pack-1', status: 'downloaded' }, sticker1), @@ -72,16 +72,12 @@ export function ReceivedPacks(): JSX.Element { return ; } -export function InstalledKnownPacks(): JSX.Element { +export function InstalledAndKnownPacks(): JSX.Element { const props = createProps({ installedPacks, knownPacks }); return ; } -InstalledKnownPacks.story = { - name: 'Installed + Known Packs', -}; - export function Empty(): JSX.Element { const props = createProps(); diff --git a/ts/components/stickers/StickerPicker.stories.tsx b/ts/components/stickers/StickerPicker.stories.tsx index ac341e07a7..f9dcbf9ec3 100644 --- a/ts/components/stickers/StickerPicker.stories.tsx +++ b/ts/components/stickers/StickerPicker.stories.tsx @@ -2,167 +2,77 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { sample } from 'lodash'; import { action } from '@storybook/addon-actions'; -import { boolean } from '@storybook/addon-knobs'; - +import type { Meta } from '@storybook/react'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; import type { Props } from './StickerPicker'; import { StickerPicker } from './StickerPicker'; -import type { StickerPackType, StickerType } from '../../state/ducks/stickers'; +import { abeSticker, createPack, packs, recentStickers } from './mocks'; const i18n = setupI18n('en', enMessages); export default { title: 'Components/Stickers/StickerPicker', -}; + component: StickerPicker, + argTypes: { + showPickerHint: { control: { type: 'boolean' } }, + }, + args: { + i18n, + onClickAddPack: action('onClickAddPack'), + onClose: action('onClose'), + onPickSticker: action('onPickSticker'), + packs: [], + recentStickers: [], + showPickerHint: false, + }, +} satisfies Meta; -export const sticker1: StickerType = { - id: 1, - url: '/fixtures/kitten-1-64-64.jpg', - packId: 'foo', - emoji: '', -}; - -export const sticker2: StickerType = { - id: 2, - url: '/fixtures/kitten-2-64-64.jpg', - packId: 'bar', - emoji: '', -}; - -export const sticker3: StickerType = { - id: 3, - url: '/fixtures/kitten-3-64-64.jpg', - packId: 'baz', - emoji: '', -}; - -export const abeSticker: StickerType = { - id: 4, - url: '/fixtures/512x515-thumbs-up-lincoln.webp', - packId: 'abe', - emoji: '', -}; - -export const wideSticker: StickerType = { - id: 5, - url: '/fixtures/1000x50-green.jpeg', - packId: 'wide', - emoji: '', -}; - -export const tallSticker: StickerType = { - id: 6, - url: '/fixtures/50x1000-teal.jpeg', - packId: 'tall', - emoji: '', -}; - -const choosableStickers = [sticker1, sticker2, sticker3, abeSticker]; - -export const createPack = ( - props: Partial, - sticker?: StickerType -): StickerPackType => ({ - id: '', - title: props.id ? `${props.id} title` : 'title', - key: '', - author: '', - isBlessed: false, - lastUsed: 0, - status: 'known', - cover: sticker, - stickerCount: 101, - stickers: sticker - ? Array(101) - .fill(0) - .map((_, id) => ({ ...sticker, id })) - : [], - ...props, -}); - -const packs = [ - createPack({ id: 'tall' }, tallSticker), - createPack({ id: 'wide' }, wideSticker), - ...Array(20) - .fill(0) - .map((_, n) => - createPack({ id: `pack-${n}` }, sample(choosableStickers) as StickerType) - ), -]; - -const recentStickers = [ - abeSticker, - sticker1, - sticker2, - sticker3, - tallSticker, - wideSticker, - { ...sticker2, id: 9999 }, -]; - -const createProps = (overrideProps: Partial = {}): Props => ({ - i18n, - onClickAddPack: action('onClickAddPack'), - onClose: action('onClose'), - onPickSticker: action('onPickSticker'), - packs: overrideProps.packs || [], - recentStickers: overrideProps.recentStickers || [], - showPickerHint: boolean( - 'showPickerHint', - overrideProps.showPickerHint || false - ), -}); - -export function Full(): JSX.Element { - const props = createProps({ packs, recentStickers }); - - return ; +export function Full(args: Props): JSX.Element { + return ( + + ); } -export function PickerHint(): JSX.Element { - const props = createProps({ packs, recentStickers, showPickerHint: true }); - - return ; +export function PickerHint(args: Props): JSX.Element { + return ( + + ); } -export function NoRecentStickers(): JSX.Element { - const props = createProps({ packs }); - - return ; +export function NoRecentStickers(args: Props): JSX.Element { + return ; } -export function Empty(): JSX.Element { - const props = createProps(); - - return ; +export function Empty(args: Props): JSX.Element { + return ; } -export function PendingDownload(): JSX.Element { +export function PendingDownload(args: Props): JSX.Element { const pack = createPack( { status: 'pending', stickers: [abeSticker] }, abeSticker ); - const props = createProps({ packs: [pack] }); - return ; + return ; } -export function Error(): JSX.Element { +export function Error(args: Props): JSX.Element { const pack = createPack( { status: 'error', stickers: [abeSticker] }, abeSticker ); - const props = createProps({ packs: [pack] }); - return ; + return ; } -export function NoCover(): JSX.Element { +export function NoCover(args: Props): JSX.Element { const pack = createPack({ status: 'error', stickers: [abeSticker] }); - const props = createProps({ packs: [pack] }); - - return ; + return ; } diff --git a/ts/components/stickers/StickerPreviewModal.stories.tsx b/ts/components/stickers/StickerPreviewModal.stories.tsx index 59bcb211e4..62025cac7f 100644 --- a/ts/components/stickers/StickerPreviewModal.stories.tsx +++ b/ts/components/stickers/StickerPreviewModal.stories.tsx @@ -2,9 +2,9 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; -import { text } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; - +import type { Meta } from '@storybook/react'; +import type { Props } from './StickerPreviewModal'; import { StickerPreviewModal } from './StickerPreviewModal'; import { setupI18n } from '../../util/setupI18n'; import enMessages from '../../../_locales/en/messages.json'; @@ -18,7 +18,9 @@ const i18n = setupI18n('en', enMessages); export default { title: 'Components/Stickers/StickerPreviewModal', -}; + argTypes: {}, + args: {}, +} satisfies Meta; const abeSticker = { id: -1, @@ -40,8 +42,8 @@ const tallSticker = { }; export function Full(): JSX.Element { - const title = text('title', 'Foo'); - const author = text('author', 'Foo McBarrington'); + const title = 'Foo'; + const author = 'Foo McBarrington'; const pack = { id: 'foo', @@ -76,8 +78,8 @@ export function Full(): JSX.Element { } export function JustFourStickers(): JSX.Element { - const title = text('title', 'Foo'); - const author = text('author', 'Foo McBarrington'); + const title = 'Foo'; + const author = 'Foo McBarrington'; const pack = { id: 'foo', @@ -104,10 +106,6 @@ export function JustFourStickers(): JSX.Element { ); } -JustFourStickers.story = { - name: 'Just four stickers', -}; - export function InitialDownload(): JSX.Element { return ( ); } - -PackDeleted.story = { - name: 'Pack deleted', -}; diff --git a/ts/components/stickers/mocks.ts b/ts/components/stickers/mocks.ts new file mode 100644 index 0000000000..0aa6a56c69 --- /dev/null +++ b/ts/components/stickers/mocks.ts @@ -0,0 +1,90 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { sample } from 'lodash'; +import type { StickerPackType, StickerType } from '../../state/ducks/stickers'; + +export const sticker1: StickerType = { + id: 1, + url: '/fixtures/kitten-1-64-64.jpg', + packId: 'foo', + emoji: '', +}; + +export const sticker2: StickerType = { + id: 2, + url: '/fixtures/kitten-2-64-64.jpg', + packId: 'bar', + emoji: '', +}; + +export const sticker3: StickerType = { + id: 3, + url: '/fixtures/kitten-3-64-64.jpg', + packId: 'baz', + emoji: '', +}; + +export const abeSticker: StickerType = { + id: 4, + url: '/fixtures/512x515-thumbs-up-lincoln.webp', + packId: 'abe', + emoji: '', +}; + +export const wideSticker: StickerType = { + id: 5, + url: '/fixtures/1000x50-green.jpeg', + packId: 'wide', + emoji: '', +}; + +export const tallSticker: StickerType = { + id: 6, + url: '/fixtures/50x1000-teal.jpeg', + packId: 'tall', + emoji: '', +}; + +const choosableStickers = [sticker1, sticker2, sticker3, abeSticker]; + +export const createPack = ( + props: Partial, + sticker?: StickerType +): StickerPackType => ({ + id: '', + title: props.id ? `${props.id} title` : 'title', + key: '', + author: '', + isBlessed: false, + lastUsed: 0, + status: 'known', + cover: sticker, + stickerCount: 101, + stickers: sticker + ? Array(101) + .fill(0) + .map((_, id) => ({ ...sticker, id })) + : [], + ...props, +}); + +export const packs = [ + createPack({ id: 'tall' }, tallSticker), + createPack({ id: 'wide' }, wideSticker), + ...Array(20) + .fill(0) + .map((_, n) => + createPack({ id: `pack-${n}` }, sample(choosableStickers) as StickerType) + ), +]; + +export const recentStickers = [ + abeSticker, + sticker1, + sticker2, + sticker3, + tallSticker, + wideSticker, + { ...sticker2, id: 9999 }, +]; diff --git a/ts/context/localeMessages.ts b/ts/context/localeMessages.ts index 994f6d0df5..6befa8c78b 100644 --- a/ts/context/localeMessages.ts +++ b/ts/context/localeMessages.ts @@ -4,3 +4,4 @@ import { ipcRenderer } from 'electron'; export const localeMessages = ipcRenderer.sendSync('locale-data'); +export const localeDisplayNames = ipcRenderer.sendSync('locale-display-names'); diff --git a/ts/groupChange.ts b/ts/groupChange.ts index 385955e15b..eb1afbf9e8 100644 --- a/ts/groupChange.ts +++ b/ts/groupChange.ts @@ -3,14 +3,16 @@ import type { LocalizerType } from './types/Util'; import type { ReplacementValuesType } from './types/I18N'; -import type { UUIDStringType } from './types/UUID'; +import type { ServiceIdString, AciString, PniString } from './types/ServiceId'; import { missingCaseError } from './util/missingCaseError'; import type { GroupV2ChangeDetailType, GroupV2ChangeType } from './groups'; import { SignalService as Proto } from './protobuf'; import * as log from './logging/log'; -export type SmartContactRendererType = (uuid: UUIDStringType) => T | string; +export type SmartContactRendererType = ( + serviceId: ServiceIdString +) => T | string; export type StringRendererType = ( id: string, i18n: LocalizerType, @@ -18,10 +20,11 @@ export type StringRendererType = ( ) => T | string; export type RenderOptionsType = { - from?: UUIDStringType; + // `from` will be a PNI when the change is "declining a PNI invite". + from?: ServiceIdString; i18n: LocalizerType; - ourACI?: UUIDStringType; - ourPNI?: UUIDStringType; + ourAci: AciString | undefined; + ourPni: PniString | undefined; renderContact: SmartContactRendererType; renderString: StringRendererType; }; @@ -70,8 +73,8 @@ export function renderChangeDetail( const { from, i18n: localizer, - ourACI, - ourPNI, + ourAci, + ourPni, renderContact, renderString, } = options; @@ -83,13 +86,15 @@ export function renderChangeDetail( return renderString(id, localizer, components); } - const isOurUuid = (uuid?: UUIDStringType): boolean => { - if (!uuid) { + const isOurServiceId = (serviceId?: ServiceIdString): boolean => { + if (!serviceId) { return false; } - return Boolean((ourACI && uuid === ourACI) || (ourPNI && uuid === ourPNI)); + return Boolean( + (ourAci && serviceId === ourAci) || (ourPni && serviceId === ourPni) + ); }; - const fromYou = isOurUuid(from); + const fromYou = isOurServiceId(from); if (detail.type === 'create') { if (fromYou) { @@ -246,8 +251,8 @@ export function renderChangeDetail( return ''; } if (detail.type === 'member-add') { - const { uuid } = detail; - const weAreJoiner = isOurUuid(uuid); + const { aci } = detail; + const weAreJoiner = isOurServiceId(aci); if (weAreJoiner) { if (fromYou) { @@ -262,25 +267,25 @@ export function renderChangeDetail( } if (fromYou) { return i18n('icu:GroupV2--member-add--other--you', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (from) { return i18n('icu:GroupV2--member-add--other--other', { adderName: renderContact(from), - addeeName: renderContact(uuid), + addeeName: renderContact(aci), }); } return i18n('icu:GroupV2--member-add--other--unknown', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (detail.type === 'member-add-from-invite') { - const { uuid, inviter } = detail; - const weAreJoiner = isOurUuid(uuid); - const weAreInviter = isOurUuid(inviter); + const { aci, inviter } = detail; + const weAreJoiner = isOurServiceId(aci); + const weAreInviter = isOurServiceId(inviter); - if (!from || from !== uuid) { + if (!from || from !== aci) { if (weAreJoiner) { // They can't be the same, no fromYou check here if (from) { @@ -293,17 +298,17 @@ export function renderChangeDetail( if (fromYou) { return i18n('icu:GroupV2--member-add--invited--you', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(aci), }); } if (from) { return i18n('icu:GroupV2--member-add--invited--other', { memberName: renderContact(from), - inviteeName: renderContact(uuid), + inviteeName: renderContact(aci), }); } return i18n('icu:GroupV2--member-add--invited--unknown', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(aci), }); } @@ -317,12 +322,12 @@ export function renderChangeDetail( } if (weAreInviter) { return i18n('icu:GroupV2--member-add--from-invite--from-you', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(aci), }); } if (inviter) { return i18n('icu:GroupV2--member-add--from-invite--other', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(aci), inviterName: renderContact(inviter), }); } @@ -330,17 +335,17 @@ export function renderChangeDetail( 'icu:GroupV2--member-add--from-invite--other-no-from', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(aci), } ); } if (detail.type === 'member-add-from-link') { - const { uuid } = detail; + const { aci } = detail; - if (fromYou && isOurUuid(uuid)) { + if (fromYou && isOurServiceId(aci)) { return i18n('icu:GroupV2--member-add-from-link--you--you'); } - if (from && uuid === from) { + if (from && aci === from) { return i18n('icu:GroupV2--member-add-from-link--other', { memberName: renderContact(from), }); @@ -350,12 +355,12 @@ export function renderChangeDetail( // from group change events, which always have a sender. log.warn('member-add-from-link change type; we have no from!'); return i18n('icu:GroupV2--member-add--other--unknown', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (detail.type === 'member-add-from-admin-approval') { - const { uuid } = detail; - const weAreJoiner = isOurUuid(uuid); + const { aci } = detail; + const weAreJoiner = isOurServiceId(aci); if (weAreJoiner) { if (from) { @@ -378,7 +383,7 @@ export function renderChangeDetail( return i18n( 'icu:GroupV2--member-add-from-admin-approval--other--you', - { joinerName: renderContact(uuid) } + { joinerName: renderContact(aci) } ); } if (from) { @@ -387,7 +392,7 @@ export function renderChangeDetail( { adminName: renderContact(from), - joinerName: renderContact(uuid), + joinerName: renderContact(aci), } ); } @@ -398,12 +403,12 @@ export function renderChangeDetail( return i18n( 'icu:GroupV2--member-add-from-admin-approval--other--unknown', - { joinerName: renderContact(uuid) } + { joinerName: renderContact(aci) } ); } if (detail.type === 'member-remove') { - const { uuid } = detail; - const weAreLeaver = isOurUuid(uuid); + const { aci } = detail; + const weAreLeaver = isOurServiceId(aci); if (weAreLeaver) { if (fromYou) { @@ -419,10 +424,10 @@ export function renderChangeDetail( if (fromYou) { return i18n('icu:GroupV2--member-remove--other--you', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } - if (from && from === uuid) { + if (from && from === aci) { return i18n('icu:GroupV2--member-remove--other--self', { memberName: renderContact(from), }); @@ -430,16 +435,16 @@ export function renderChangeDetail( if (from) { return i18n('icu:GroupV2--member-remove--other--other', { adminName: renderContact(from), - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } return i18n('icu:GroupV2--member-remove--other--unknown', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (detail.type === 'member-privilege') { - const { uuid, newPrivilege } = detail; - const weAreMember = isOurUuid(uuid); + const { aci, newPrivilege } = detail; + const weAreMember = isOurServiceId(aci); if (newPrivilege === RoleEnum.ADMINISTRATOR) { if (weAreMember) { @@ -456,17 +461,17 @@ export function renderChangeDetail( if (fromYou) { return i18n('icu:GroupV2--member-privilege--promote--other--you', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (from) { return i18n('icu:GroupV2--member-privilege--promote--other--other', { adminName: renderContact(from), - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } return i18n('icu:GroupV2--member-privilege--promote--other--unknown', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (newPrivilege === RoleEnum.DEFAULT) { @@ -481,7 +486,7 @@ export function renderChangeDetail( if (fromYou) { return i18n('icu:GroupV2--member-privilege--demote--other--you', { - memberName: renderContact(uuid), + memberName: renderContact(aci), }); } if (from) { @@ -490,14 +495,14 @@ export function renderChangeDetail( { adminName: renderContact(from), - memberName: renderContact(uuid), + memberName: renderContact(aci), } ); } return i18n( 'icu:GroupV2--member-privilege--demote--other--unknown', - { memberName: renderContact(uuid) } + { memberName: renderContact(aci) } ); } log.warn( @@ -506,8 +511,8 @@ export function renderChangeDetail( return ''; } if (detail.type === 'pending-add-one') { - const { uuid } = detail; - const weAreInvited = isOurUuid(uuid); + const { serviceId } = detail; + const weAreInvited = isOurServiceId(serviceId); if (weAreInvited) { if (from) { return i18n('icu:GroupV2--pending-add--one--you--other', { @@ -518,7 +523,7 @@ export function renderChangeDetail( } if (fromYou) { return i18n('icu:GroupV2--pending-add--one--other--you', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(serviceId), }); } if (from) { @@ -547,23 +552,23 @@ export function renderChangeDetail( }); } if (detail.type === 'pending-remove-one') { - const { inviter, uuid } = detail; - const weAreInviter = isOurUuid(inviter); - const weAreInvited = isOurUuid(uuid); - const sentByInvited = Boolean(from && from === uuid); + const { inviter, serviceId } = detail; + const weAreInviter = isOurServiceId(inviter); + const weAreInvited = isOurServiceId(serviceId); + const sentByInvited = Boolean(from && from === serviceId); const sentByInviter = Boolean(from && inviter && from === inviter); if (weAreInviter) { if (sentByInvited) { return i18n('icu:GroupV2--pending-remove--decline--you', { - inviteeName: renderContact(uuid), + inviteeName: renderContact(serviceId), }); } if (fromYou) { return i18n( 'icu:GroupV2--pending-remove--revoke-invite-from-you--one--you', - { inviteeName: renderContact(uuid) } + { inviteeName: renderContact(serviceId) } ); } if (from) { @@ -572,14 +577,14 @@ export function renderChangeDetail( { adminName: renderContact(from), - inviteeName: renderContact(uuid), + inviteeName: renderContact(serviceId), } ); } return i18n( 'icu:GroupV2--pending-remove--revoke-invite-from-you--one--unknown', - { inviteeName: renderContact(uuid) } + { inviteeName: renderContact(serviceId) } ); } if (sentByInvited) { @@ -643,7 +648,7 @@ export function renderChangeDetail( } if (detail.type === 'pending-remove-many') { const { count, inviter } = detail; - const weAreInviter = isOurUuid(inviter); + const weAreInviter = isOurServiceId(inviter); if (weAreInviter) { if (fromYou) { @@ -722,19 +727,19 @@ export function renderChangeDetail( ); } if (detail.type === 'admin-approval-add-one') { - const { uuid } = detail; - const weAreJoiner = isOurUuid(uuid); + const { aci } = detail; + const weAreJoiner = isOurServiceId(aci); if (weAreJoiner) { return i18n('icu:GroupV2--admin-approval-add-one--you'); } return i18n('icu:GroupV2--admin-approval-add-one--other', { - joinerName: renderContact(uuid), + joinerName: renderContact(aci), }); } if (detail.type === 'admin-approval-remove-one') { - const { uuid } = detail; - const weAreJoiner = isOurUuid(uuid); + const { aci } = detail; + const weAreJoiner = isOurServiceId(aci); if (weAreJoiner) { if (fromYou) { @@ -747,14 +752,14 @@ export function renderChangeDetail( return i18n( 'icu:GroupV2--admin-approval-remove-one--other--you', - { joinerName: renderContact(uuid) } + { joinerName: renderContact(aci) } ); } - if (from && from === uuid) { + if (from && from === aci) { return i18n( 'icu:GroupV2--admin-approval-remove-one--other--own', - { joinerName: renderContact(uuid) } + { joinerName: renderContact(aci) } ); } if (from) { @@ -763,7 +768,7 @@ export function renderChangeDetail( { adminName: renderContact(from), - joinerName: renderContact(uuid), + joinerName: renderContact(aci), } ); } @@ -773,20 +778,20 @@ export function renderChangeDetail( return i18n( 'icu:GroupV2--admin-approval-remove-one--other--own', - { joinerName: renderContact(uuid) } + { joinerName: renderContact(aci) } ); } if (detail.type === 'admin-approval-bounce') { - const { uuid, times, isApprovalPending } = detail; + const { aci, times, isApprovalPending } = detail; let firstMessage: T | string; if (times === 1) { firstMessage = i18n('icu:GroupV2--admin-approval-bounce--one', { - joinerName: renderContact(uuid), + joinerName: renderContact(aci), }); } else { firstMessage = i18n('icu:GroupV2--admin-approval-bounce', { - joinerName: renderContact(uuid), + joinerName: renderContact(aci), numberOfRequests: times, }); } @@ -798,7 +803,7 @@ export function renderChangeDetail( const secondMessage = renderChangeDetail( { type: 'admin-approval-add-one', - uuid, + aci, }, options ); diff --git a/ts/groups.ts b/ts/groups.ts index b29feb7fbb..23d8e0a179 100644 --- a/ts/groups.ts +++ b/ts/groups.ts @@ -23,8 +23,8 @@ import dataInterface from './sql/Client'; import { toWebSafeBase64, fromWebSafeBase64 } from './util/webSafeBase64'; import { assertDev, strictAssert } from './util/assert'; import { isMoreRecentThan } from './util/timestamp'; -import { MINUTE, DurationInSeconds } from './util/durations'; -import { normalizeUuid } from './util/normalizeUuid'; +import { MINUTE, DurationInSeconds, SECOND } from './util/durations'; +import { drop } from './util/drop'; import { dropNull } from './util/dropNull'; import type { ConversationAttributesType, @@ -39,12 +39,14 @@ import { decodeProfileKeyCredentialPresentation, decryptGroupBlob, decryptProfileKey, - decryptUuid, + decryptAci, + decryptPni, + decryptServiceId, deriveGroupID, deriveGroupPublicParams, deriveGroupSecretParams, encryptGroupBlob, - encryptUuid, + encryptServiceId, getAuthCredentialPresentation, getClientZkAuthOperations, getClientZkGroupCipher, @@ -73,8 +75,13 @@ import { } from './util/whatTypeOfConversation'; import * as Bytes from './Bytes'; import type { AvatarDataType } from './types/Avatar'; -import { UUID, UUIDKind, isValidUuid } from './types/UUID'; -import type { UUIDStringType } from './types/UUID'; +import type { ServiceIdString, AciString, PniString } from './types/ServiceId'; +import { + ServiceIdKind, + isPniString, + isServiceIdString, +} from './types/ServiceId'; +import { isAciString } from './util/isAciString'; import * as Errors from './types/errors'; import { SignalService as Proto } from './protobuf'; import { isNotNil } from './util/isNotNil'; @@ -87,6 +94,8 @@ import { import { ReadStatus } from './messages/MessageReadStatus'; import { SeenStatus } from './MessageSeenStatus'; import { incrementMessageCounter } from './util/incrementMessageCounter'; +import { sleep } from './util/sleep'; +import { groupInvitesRoute } from './util/signalRoutes'; type AccessRequiredEnum = Proto.AccessControl.AccessRequired; @@ -135,34 +144,34 @@ type GroupV2GroupLinkRemoveChangeType = { type GroupV2MemberAddChangeType = { type: 'member-add'; - uuid: UUIDStringType; + aci: AciString; }; type GroupV2MemberAddFromInviteChangeType = { type: 'member-add-from-invite'; - uuid: UUIDStringType; - inviter?: UUIDStringType; + aci: AciString; + inviter?: AciString; }; type GroupV2MemberAddFromLinkChangeType = { type: 'member-add-from-link'; - uuid: UUIDStringType; + aci: AciString; }; type GroupV2MemberAddFromAdminApprovalChangeType = { type: 'member-add-from-admin-approval'; - uuid: UUIDStringType; + aci: AciString; }; type GroupV2MemberPrivilegeChangeType = { type: 'member-privilege'; - uuid: UUIDStringType; + aci: AciString; newPrivilege: number; }; type GroupV2MemberRemoveChangeType = { type: 'member-remove'; - uuid: UUIDStringType; + aci: AciString; }; type GroupV2PendingAddOneChangeType = { type: 'pending-add-one'; - uuid: UUIDStringType; + serviceId: ServiceIdString; }; type GroupV2PendingAddManyChangeType = { type: 'pending-add-many'; @@ -171,32 +180,32 @@ type GroupV2PendingAddManyChangeType = { // Note: pending-remove is only used if user didn't also join the group at the same time type GroupV2PendingRemoveOneChangeType = { type: 'pending-remove-one'; - uuid: UUIDStringType; - inviter?: UUIDStringType; + serviceId: ServiceIdString; + inviter?: AciString; }; // Note: pending-remove is only used if user didn't also join the group at the same time type GroupV2PendingRemoveManyChangeType = { type: 'pending-remove-many'; count: number; - inviter?: UUIDStringType; + inviter?: AciString; }; type GroupV2AdminApprovalAddOneChangeType = { type: 'admin-approval-add-one'; - uuid: UUIDStringType; + aci: AciString; }; // Note: admin-approval-remove-one is only used if user didn't also join the group at // the same time type GroupV2AdminApprovalRemoveOneChangeType = { type: 'admin-approval-remove-one'; - uuid: UUIDStringType; - inviter?: UUIDStringType; + aci: AciString; + inviter?: AciString; }; type GroupV2AdminApprovalBounceChangeType = { type: 'admin-approval-bounce'; times: number; isApprovalPending: boolean; - uuid: UUIDStringType; + aci: AciString; }; export type GroupV2DescriptionChangeType = { type: 'description'; @@ -236,7 +245,7 @@ export type GroupV2ChangeDetailType = | GroupV2TitleChangeType; export type GroupV2ChangeType = { - from?: UUIDStringType; + from?: ServiceIdString; details: Array; }; @@ -260,16 +269,12 @@ if (!isNumber(MAX_MESSAGE_SCHEMA)) { ); } -type MemberType = { - profileKey: string; - uuid: UUIDStringType; -}; type UpdatesResultType = { // The array of new messages to be added into the message timeline groupChangeMessages: Array; - // The set of members in the group, and we largely just pull profile keys for each, + // The map of members in the group, and we largely just pull profile keys for each, // because the group membership is updated in newAttributes - members: Array; + newProfileKeys: Map; // To be merged into the conversation model newAttributes: ConversationAttributesType; }; @@ -287,7 +292,7 @@ type BasicMessageType = Pick< type GroupV2ChangeMessageType = { type: 'group-v2-change'; -} & Pick; +} & Pick; type GroupV1MigrationMessageType = { type: 'group-v1-migration'; @@ -300,7 +305,7 @@ type TimerNotificationMessageType = { type: 'timer-notification'; } & Pick< MessageAttributesType, - 'sourceUuid' | 'flags' | 'expirationTimerUpdate' + 'sourceServiceId' | 'flags' | 'expirationTimerUpdate' >; type GroupChangeMessageType = BasicMessageType & @@ -379,16 +384,16 @@ export function buildGroupLink( }, }).finish(); - const hash = toWebSafeBase64(Bytes.toBase64(bytes)); + const inviteCode = toWebSafeBase64(Bytes.toBase64(bytes)); - return `https://signal.group/#${hash}`; + return groupInvitesRoute.toWebUrl({ inviteCode }).toString(); } -export function parseGroupLink(hash: string): { +export function parseGroupLink(value: string): { masterKey: string; inviteLinkPassword: string; } { - const base64 = fromWebSafeBase64(hash); + const base64 = fromWebSafeBase64(value); const buffer = Bytes.fromBase64(base64); const inviteLinkProto = Proto.GroupInviteLink.decode(buffer); @@ -591,7 +596,7 @@ function buildGroupProto( proto.members = (attributes.membersV2 || []).map(item => { const member = new Proto.Member(); - const conversation = window.ConversationController.get(item.uuid); + const conversation = window.ConversationController.get(item.aci); if (!conversation) { throw new Error(`buildGroupProto/${logId}: no conversation for member!`); } @@ -614,31 +619,34 @@ function buildGroupProto( return member; }); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.storage.user.getCheckedAci(); - const ourACICipherTextBuffer = encryptUuid(clientZkGroupCipher, ourACI); + const ourAciCipherTextBuffer = encryptServiceId(clientZkGroupCipher, ourAci); proto.membersPendingProfileKey = (attributes.pendingMembersV2 || []).map( item => { const pendingMember = new Proto.MemberPendingProfileKey(); const member = new Proto.Member(); - const conversation = window.ConversationController.get(item.uuid); + const conversation = window.ConversationController.get(item.serviceId); if (!conversation) { throw new Error('buildGroupProto: no conversation for pending member!'); } - const uuid = conversation.getCheckedUuid( - 'buildGroupProto: pending member was missing uuid!' + const serviceId = conversation.getCheckedServiceId( + 'buildGroupProto: pending member was missing serviceId!' ); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const uuidCipherTextBuffer = encryptServiceId( + clientZkGroupCipher, + serviceId + ); member.userId = uuidCipherTextBuffer; member.role = item.role || MEMBER_ROLE_ENUM.DEFAULT; pendingMember.member = member; pendingMember.timestamp = Long.fromNumber(item.timestamp); - pendingMember.addedByUserId = ourACICipherTextBuffer; + pendingMember.addedByUserId = ourAciCipherTextBuffer; return pendingMember; } @@ -678,8 +686,8 @@ export async function buildAddMembersChange( ); const clientZkGroupCipher = getClientZkGroupCipher(secretParams); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); - const ourACICipherTextBuffer = encryptUuid(clientZkGroupCipher, ourACI); + const ourAci = window.storage.user.getCheckedAci(); + const ourAciCipherTextBuffer = encryptServiceId(clientZkGroupCipher, ourAci); const now = Date.now(); @@ -699,11 +707,11 @@ export async function buildAddMembersChange( return; } - const uuid = contact.getUuid(); - if (!uuid) { + const serviceId = contact.getServiceId(); + if (!serviceId) { assertDev( false, - `buildAddMembersChange/${logId}: missing UUID; skipping` + `buildAddMembersChange/${logId}: missing serviceId; skipping` ); return; } @@ -717,7 +725,7 @@ export async function buildAddMembersChange( const profileKeyCredential = contact.get('profileKeyCredential'); const member = new Proto.Member(); - member.userId = encryptUuid(clientZkGroupCipher, uuid); + member.userId = encryptServiceId(clientZkGroupCipher, serviceId); member.role = MEMBER_ROLE_ENUM.DEFAULT; member.joinedAtVersion = newGroupVersion; @@ -739,7 +747,7 @@ export async function buildAddMembersChange( } else { const memberPendingProfileKey = new Proto.MemberPendingProfileKey(); memberPendingProfileKey.member = member; - memberPendingProfileKey.addedByUserId = ourACICipherTextBuffer; + memberPendingProfileKey.addedByUserId = ourAciCipherTextBuffer; memberPendingProfileKey.timestamp = Long.fromNumber(now); const addPendingMemberAction = @@ -750,10 +758,13 @@ export async function buildAddMembersChange( } const doesMemberNeedUnban = conversation.bannedMembersV2?.find( - bannedMember => bannedMember.uuid === uuid.toString() + bannedMember => bannedMember.serviceId === serviceId ); if (doesMemberNeedUnban) { - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const uuidCipherTextBuffer = encryptServiceId( + clientZkGroupCipher, + serviceId + ); const deleteMemberBannedAction = new Proto.GroupChange.Actions.DeleteMemberBannedAction(); @@ -1003,20 +1014,20 @@ export function buildAccessControlMembersChange( export function _maybeBuildAddBannedMemberActions({ clientZkGroupCipher, group, - ourUuid, - uuid, + ourAci, + serviceId, }: { clientZkGroupCipher: ClientZkGroupCipher; group: Pick; - ourUuid: UUID; - uuid: UUID; + ourAci: AciString; + serviceId: ServiceIdString; }): Pick< Proto.GroupChange.IActions, 'addMembersBanned' | 'deleteMembersBanned' > { const doesMemberNeedBan = - !group.bannedMembersV2?.find(member => member.uuid === uuid.toString()) && - !uuid.isEqual(ourUuid); + !group.bannedMembersV2?.find(member => member.serviceId === serviceId) && + serviceId !== ourAci; if (!doesMemberNeedBan) { return {}; } @@ -1039,9 +1050,9 @@ export function _maybeBuildAddBannedMemberActions({ const deleteMemberBannedAction = new Proto.GroupChange.Actions.DeleteMemberBannedAction(); - deleteMemberBannedAction.deletedUserId = encryptUuid( + deleteMemberBannedAction.deletedUserId = encryptServiceId( clientZkGroupCipher, - new UUID(bannedMember.uuid) + bannedMember.serviceId ); return deleteMemberBannedAction; @@ -1051,7 +1062,7 @@ export function _maybeBuildAddBannedMemberActions({ const addMemberBannedAction = new Proto.GroupChange.Actions.AddMemberBannedAction(); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const uuidCipherTextBuffer = encryptServiceId(clientZkGroupCipher, serviceId); addMemberBannedAction.added = new Proto.MemberBanned(); addMemberBannedAction.added.userId = uuidCipherTextBuffer; @@ -1064,12 +1075,12 @@ export function _maybeBuildAddBannedMemberActions({ // TODO AND-1101 export function buildDeletePendingAdminApprovalMemberChange({ group, - ourUuid, - uuid, + ourAci, + aci, }: { group: ConversationAttributesType; - ourUuid: UUID; - uuid: UUID; + ourAci: AciString; + aci: AciString; }): Proto.GroupChange.Actions { const actions = new Proto.GroupChange.Actions(); @@ -1079,7 +1090,7 @@ export function buildDeletePendingAdminApprovalMemberChange({ ); } const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const uuidCipherTextBuffer = encryptServiceId(clientZkGroupCipher, aci); const deleteMemberPendingAdminApproval = new Proto.GroupChange.Actions.DeleteMemberPendingAdminApprovalAction(); @@ -1094,8 +1105,8 @@ export function buildDeletePendingAdminApprovalMemberChange({ _maybeBuildAddBannedMemberActions({ clientZkGroupCipher, group, - ourUuid, - uuid, + ourAci, + serviceId: aci, }); if (addMembersBanned) { @@ -1151,13 +1162,13 @@ export function buildAddMember({ group, profileKeyCredentialBase64, serverPublicParamsBase64, - uuid, + serviceId, }: { group: ConversationAttributesType; profileKeyCredentialBase64: string; serverPublicParamsBase64: string; joinFromInviteLink?: boolean; - uuid: UUID; + serviceId: ServiceIdString; }): Proto.GroupChange.Actions { const MEMBER_ROLE_ENUM = Proto.Member.Role; @@ -1187,16 +1198,16 @@ export function buildAddMember({ actions.addMembers = [addMember]; const doesMemberNeedUnban = group.bannedMembersV2?.find( - member => member.uuid === uuid.toString() + member => member.serviceId === serviceId ); if (doesMemberNeedUnban) { const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const userIdCipherText = encryptServiceId(clientZkGroupCipher, serviceId); const deleteMemberBannedAction = new Proto.GroupChange.Actions.DeleteMemberBannedAction(); - deleteMemberBannedAction.deletedUserId = uuidCipherTextBuffer; + deleteMemberBannedAction.deletedUserId = userIdCipherText; actions.deleteMembersBanned = [deleteMemberBannedAction]; } @@ -1204,10 +1215,10 @@ export function buildAddMember({ } export function buildDeletePendingMemberChange({ - uuids, + serviceIds, group, }: { - uuids: ReadonlyArray; + serviceIds: ReadonlyArray; group: ConversationAttributesType; }): Proto.GroupChange.Actions { const actions = new Proto.GroupChange.Actions(); @@ -1219,8 +1230,11 @@ export function buildDeletePendingMemberChange({ } const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const deletePendingMembers = uuids.map(uuid => { - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const deletePendingMembers = serviceIds.map(serviceId => { + const uuidCipherTextBuffer = encryptServiceId( + clientZkGroupCipher, + serviceId + ); const deletePendingMember = new Proto.GroupChange.Actions.DeleteMemberPendingProfileKeyAction(); deletePendingMember.deletedUserId = uuidCipherTextBuffer; @@ -1235,12 +1249,12 @@ export function buildDeletePendingMemberChange({ export function buildDeleteMemberChange({ group, - ourUuid, - uuid, + ourAci, + serviceId, }: { group: ConversationAttributesType; - ourUuid: UUID; - uuid: UUID; + ourAci: AciString; + serviceId: ServiceIdString; }): Proto.GroupChange.Actions { const actions = new Proto.GroupChange.Actions(); @@ -1248,7 +1262,7 @@ export function buildDeleteMemberChange({ throw new Error('buildDeleteMemberChange: group was missing secretParams!'); } const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const uuidCipherTextBuffer = encryptServiceId(clientZkGroupCipher, serviceId); const deleteMember = new Proto.GroupChange.Actions.DeleteMemberAction(); deleteMember.deletedUserId = uuidCipherTextBuffer; @@ -1260,8 +1274,8 @@ export function buildDeleteMemberChange({ _maybeBuildAddBannedMemberActions({ clientZkGroupCipher, group, - ourUuid, - uuid, + ourAci, + serviceId, }); if (addMembersBanned) { @@ -1275,10 +1289,10 @@ export function buildDeleteMemberChange({ } export function buildAddBannedMemberChange({ - uuid, + serviceId, group, }: { - uuid: UUID; + serviceId: ServiceIdString; group: ConversationAttributesType; }): Proto.GroupChange.Actions { const actions = new Proto.GroupChange.Actions(); @@ -1289,23 +1303,21 @@ export function buildAddBannedMemberChange({ ); } const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const userIdCipherText = encryptServiceId(clientZkGroupCipher, serviceId); const addMemberBannedAction = new Proto.GroupChange.Actions.AddMemberBannedAction(); addMemberBannedAction.added = new Proto.MemberBanned(); - addMemberBannedAction.added.userId = uuidCipherTextBuffer; + addMemberBannedAction.added.userId = userIdCipherText; actions.addMembersBanned = [addMemberBannedAction]; - if ( - group.pendingAdminApprovalV2?.some(item => item.uuid === uuid.toString()) - ) { + if (group.pendingAdminApprovalV2?.some(item => item.aci === serviceId)) { const deleteMemberPendingAdminApprovalAction = new Proto.GroupChange.Actions.DeleteMemberPendingAdminApprovalAction(); - deleteMemberPendingAdminApprovalAction.deletedUserId = uuidCipherTextBuffer; + deleteMemberPendingAdminApprovalAction.deletedUserId = userIdCipherText; actions.deleteMemberPendingAdminApprovals = [ deleteMemberPendingAdminApprovalAction, @@ -1318,11 +1330,11 @@ export function buildAddBannedMemberChange({ } export function buildModifyMemberRoleChange({ - uuid, + serviceId, group, role, }: { - uuid: UUID; + serviceId: ServiceIdString; group: ConversationAttributesType; role: number; }): Proto.GroupChange.Actions { @@ -1333,10 +1345,10 @@ export function buildModifyMemberRoleChange({ } const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const userIdCipherText = encryptServiceId(clientZkGroupCipher, serviceId); const toggleAdmin = new Proto.GroupChange.Actions.ModifyMemberRoleAction(); - toggleAdmin.userId = uuidCipherTextBuffer; + toggleAdmin.userId = userIdCipherText; toggleAdmin.role = role; actions.version = (group.revision || 0) + 1; @@ -1347,10 +1359,10 @@ export function buildModifyMemberRoleChange({ export function buildPromotePendingAdminApprovalMemberChange({ group, - uuid, + aci, }: { group: ConversationAttributesType; - uuid: UUID; + aci: AciString; }): Proto.GroupChange.Actions { const MEMBER_ROLE_ENUM = Proto.Member.Role; const actions = new Proto.GroupChange.Actions(); @@ -1362,11 +1374,11 @@ export function buildPromotePendingAdminApprovalMemberChange({ } const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); - const uuidCipherTextBuffer = encryptUuid(clientZkGroupCipher, uuid); + const userIdCipher = encryptServiceId(clientZkGroupCipher, aci); const promotePendingMember = new Proto.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction(); - promotePendingMember.userId = uuidCipherTextBuffer; + promotePendingMember.userId = userIdCipher; promotePendingMember.role = MEMBER_ROLE_ENUM.DEFAULT; actions.version = (group.revision || 0) + 1; @@ -1739,7 +1751,7 @@ export async function fetchMembershipProof({ secretParams, request: (sender, options) => sender.getGroupMembershipToken(options), }); - return response.token; + return dropNull(response.token); } // Creating a group @@ -1779,7 +1791,7 @@ export async function createGroupV2( const secretParams = Bytes.toBase64(fields.secretParams); const publicParams = Bytes.toBase64(fields.publicParams); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI).toString(); + const ourAci = window.storage.user.getCheckedAci(); const ourConversation = window.ConversationController.getOurConversationOrThrow(); @@ -1790,7 +1802,7 @@ export async function createGroupV2( const membersV2: Array = [ { - uuid: ourACI, + aci: ourAci, role: MEMBER_ROLE_ENUM.ADMINISTRATOR, joinedAtVersion: 0, }, @@ -1810,9 +1822,12 @@ export async function createGroupV2( return; } - const contactUuid = contact.get('uuid'); - if (!contactUuid) { - assertDev(false, `createGroupV2/${logId}: missing UUID; skipping`); + const contactServiceId = contact.getServiceId(); + if (!contactServiceId) { + assertDev( + false, + `createGroupV2/${logId}: missing service id; skipping` + ); return; } @@ -1822,15 +1837,16 @@ export async function createGroupV2( } if (contact.get('profileKey') && contact.get('profileKeyCredential')) { + strictAssert(isAciString(contactServiceId), 'profile key without ACI'); membersV2.push({ - uuid: contactUuid, + aci: contactServiceId, role: MEMBER_ROLE_ENUM.DEFAULT, joinedAtVersion: 0, }); } else { pendingMembersV2.push({ - addedByUserId: ourACI, - uuid: contactUuid, + addedByUserId: ourAci, + serviceId: contactServiceId, timestamp: Date.now(), role: MEMBER_ROLE_ENUM.DEFAULT, }); @@ -1945,7 +1961,7 @@ export async function createGroupV2( { ...protoAndConversationAttributes, active_at: now, - addedBy: ourACI, + addedBy: ourAci, avatar: avatarAttribute, avatars, groupVersion: 2, @@ -1976,7 +1992,7 @@ export async function createGroupV2( const createdTheGroupMessage: MessageAttributesType = { ...generateBasicMessage(), type: 'group-v2-change', - sourceUuid: ourACI, + sourceServiceId: ourAci, conversationId: conversation.id, readStatus: ReadStatus.Read, received_at: incrementMessageCounter(), @@ -1985,16 +2001,20 @@ export async function createGroupV2( seenStatus: SeenStatus.Seen, sent_at: timestamp, groupV2Change: { - from: ourACI, + from: ourAci, details: [{ type: 'create' }], }, }; await dataInterface.saveMessages([createdTheGroupMessage], { forceSave: true, - ourUuid: ourACI, + ourAci, }); - const model = new window.Whisper.Message(createdTheGroupMessage); - window.MessageController.register(model.id, model); + let model = new window.Whisper.Message(createdTheGroupMessage); + model = window.MessageCache.__DEPRECATED$register( + model.id, + model, + 'createGroupV2' + ); conversation.trigger('newmessage', model); if (expireTimer) { @@ -2087,9 +2107,9 @@ export async function isGroupEligibleToMigrate( return false; } - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.storage.user.getCheckedAci(); const areWeMember = - !conversation.get('left') && conversation.hasMember(ourACI); + !conversation.get('left') && conversation.hasMember(ourAci); if (!areWeMember) { return false; } @@ -2102,7 +2122,7 @@ export async function isGroupEligibleToMigrate( if (!contact) { return false; } - if (!contact.get('uuid')) { + if (!contact.getServiceId()) { return false; } } @@ -2129,7 +2149,7 @@ export async function getGroupMigrationMembers( ); } - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI).toString(); + const ourAci = window.storage.user.getCheckedAci(); let areWeMember = false; let areWeInvited = false; @@ -2157,10 +2177,10 @@ export async function getGroupMigrationMembers( return null; } - const contactUuid = contact.get('uuid'); - if (!contactUuid) { + const contactAci = contact.getAci(); + if (!contactAci) { log.warn( - `getGroupMigrationMembers/${logId}: membersV2 - missing uuid for ${e164}, skipping.` + `getGroupMigrationMembers/${logId}: membersV2 - missing aci for ${e164}, skipping.` ); return null; } @@ -2193,7 +2213,7 @@ export async function getGroupMigrationMembers( memberLookup[conversationId] = true; return { - uuid: contactUuid, + aci: contactAci, role: MEMBER_ROLE_ENUM.ADMINISTRATOR, joinedAtVersion: 0, }; @@ -2229,7 +2249,7 @@ export async function getGroupMigrationMembers( return null; } - const contactUuid = contact.get('uuid'); + const contactUuid = contact.getServiceId(); if (!contactUuid) { log.warn( `getGroupMigrationMembers/${logId}: pendingMembersV2 - missing uuid for ${e164}, skipping.` @@ -2243,9 +2263,9 @@ export async function getGroupMigrationMembers( } return { - uuid: contactUuid, + serviceId: contactUuid, timestamp: now, - addedByUserId: ourACI, + addedByUserId: ourAci, role: MEMBER_ROLE_ENUM.ADMINISTRATOR, }; }) @@ -2409,7 +2429,11 @@ export async function initiateMigrationToGroupV2( groupChangeMessages.push({ ...generateBasicMessage(), type: 'group-v1-migration', - invitedGV2Members: pendingMembersV2, + invitedGV2Members: pendingMembersV2.map( + ({ serviceId: uuid, ...rest }) => { + return { ...rest, uuid }; + } + ), droppedGV2MemberIds, readStatus: ReadStatus.Read, seenStatus: SeenStatus.Seen, @@ -2420,7 +2444,7 @@ export async function initiateMigrationToGroupV2( updates: { newAttributes, groupChangeMessages, - members: [], + newProfileKeys: new Map(), }, }); @@ -2491,21 +2515,21 @@ export function buildMigrationBubble( previousGroupV1MembersIds: ReadonlyArray, newAttributes: ConversationAttributesType ): GroupChangeMessageType { - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); - const ourPNI = window.storage.user.getUuid(UUIDKind.PNI); + const ourAci = window.storage.user.getCheckedAci(); + const ourPni = window.storage.user.getPni(); const ourConversationId = window.ConversationController.getOurConversationId(); // Assemble items to commemorate this event for the timeline.. const combinedConversationIds: Array = [ - ...(newAttributes.membersV2 || []).map(item => item.uuid), - ...(newAttributes.pendingMembersV2 || []).map(item => item.uuid), - ].map(uuid => { + ...(newAttributes.membersV2 || []).map(item => item.aci), + ...(newAttributes.pendingMembersV2 || []).map(item => item.serviceId), + ].map(serviceId => { const conversation = window.ConversationController.lookupOrCreate({ - uuid, + serviceId, reason: 'buildMigrationBubble', }); - strictAssert(conversation, `Conversation not found for ${uuid}`); + strictAssert(conversation, `Conversation not found for ${serviceId}`); return conversation.id; }); const droppedMemberIds: Array = difference( @@ -2513,15 +2537,11 @@ export function buildMigrationBubble( combinedConversationIds ).filter(id => id && id !== ourConversationId); const invitedMembers = (newAttributes.pendingMembersV2 || []).filter( - item => - item.uuid !== ourACI.toString() && - !(ourPNI && item.uuid === ourPNI.toString()) + item => item.serviceId !== ourAci && !(ourPni && item.serviceId === ourPni) ); const areWeInvited = (newAttributes.pendingMembersV2 || []).some( - item => - item.uuid === ourACI.toString() || - (ourPNI && item.uuid === ourPNI.toString()) + item => item.serviceId === ourAci || (ourPni && item.serviceId === ourPni) ); return { @@ -2529,7 +2549,9 @@ export function buildMigrationBubble( type: 'group-v1-migration', groupMigration: { areWeInvited, - invitedMembers, + invitedMembers: invitedMembers.map(({ serviceId: uuid, ...rest }) => { + return { ...rest, uuid }; + }), droppedMemberIds, }, }; @@ -2625,7 +2647,7 @@ export async function joinGroupV2ViaLinkAndMigrate({ updates: { newAttributes, groupChangeMessages, - members: [], + newProfileKeys: new Map(), }, }); @@ -2658,8 +2680,8 @@ export async function respondToGroupV2Migration({ ); } - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); - const wereWePreviouslyAMember = conversation.hasMember(ourACI); + const ourAci = window.storage.user.getCheckedAci(); + const wereWePreviouslyAMember = conversation.hasMember(ourAci); // Derive GroupV2 fields const groupV1IdBuffer = Bytes.fromBinary(previousGroupV1Id); @@ -2762,7 +2784,7 @@ export async function respondToGroupV2Migration({ addedBy: undefined, left: true, members: (conversation.get('members') || []).filter( - item => item !== ourACI.toString() && item !== ourNumber + item => item !== ourAci && item !== ourNumber ), }, groupChangeMessages: [ @@ -2778,7 +2800,7 @@ export async function respondToGroupV2Migration({ details: [ { type: 'member-remove' as const, - uuid: ourACI.toString(), + aci: ourAci, }, ], }, @@ -2786,7 +2808,7 @@ export async function respondToGroupV2Migration({ seenStatus: SeenStatus.Unseen, }, ], - members: [], + newProfileKeys: new Map(), }, }); return; @@ -2808,7 +2830,7 @@ export async function respondToGroupV2Migration({ seenStatus: SeenStatus.Seen, }, ], - members: [], + newProfileKeys: new Map(), }, }); return; @@ -2845,10 +2867,10 @@ export async function respondToGroupV2Migration({ }); const areWeInvited = (newAttributes.pendingMembersV2 || []).some( - item => item.uuid === ourACI.toString() + item => item.serviceId === ourAci ); const areWeMember = (newAttributes.membersV2 || []).some( - item => item.uuid === ourACI.toString() + item => item.aci === ourAci ); if (!areWeInvited && !areWeMember) { // Add a message to the timeline saying the user was removed. This shouldn't happen. @@ -2859,7 +2881,7 @@ export async function respondToGroupV2Migration({ details: [ { type: 'member-remove' as const, - uuid: ourACI.toString(), + aci: ourAci, }, ], }, @@ -2879,7 +2901,7 @@ export async function respondToGroupV2Migration({ updates: { newAttributes, groupChangeMessages, - members: profileKeysToMembers(newProfileKeys), + newProfileKeys: profileKeysToMap(newProfileKeys), }, }); @@ -3015,28 +3037,25 @@ async function updateGroup( ): Promise { const logId = conversation.idForLogging(); - const { newAttributes, groupChangeMessages, members } = updates; - const ourACI = window.textsecure.storage.user.getCheckedUuid(UUIDKind.ACI); - const ourPNI = window.textsecure.storage.user.getUuid(UUIDKind.PNI); + const { newAttributes, groupChangeMessages, newProfileKeys } = updates; + const ourAci = window.textsecure.storage.user.getCheckedAci(); + const ourPni = window.textsecure.storage.user.getPni(); const startingRevision = conversation.get('revision'); const endingRevision = newAttributes.revision; const wasMemberOrPending = - conversation.hasMember(ourACI) || - conversation.isMemberPending(ourACI) || - (ourPNI && conversation.isMemberPending(ourPNI)); + conversation.hasMember(ourAci) || + conversation.isMemberPending(ourAci) || + (ourPni && conversation.isMemberPending(ourPni)); const isMemberOrPending = !newAttributes.left || newAttributes.pendingMembersV2?.some( - item => - item.uuid === ourACI.toString() || item.uuid === ourPNI?.toString() + item => item.serviceId === ourAci || item.serviceId === ourPni ); const isMemberOrPendingOrAwaitingApproval = isMemberOrPending || - newAttributes.pendingAdminApprovalV2?.some( - item => item.uuid === ourACI.toString() - ); + newAttributes.pendingAdminApprovalV2?.some(item => item.aci === ourAci); const isInitialDataFetch = !isNumber(startingRevision) && isNumber(endingRevision); @@ -3088,22 +3107,19 @@ async function updateGroup( const contactsWithoutProfileKey = new Array(); // Capture profile key for each member in the group, if we don't have it yet - members.forEach(member => { - const contact = window.ConversationController.getOrCreate( - member.uuid, - 'private' - ); + for (const [aci, profileKey] of newProfileKeys) { + const contact = window.ConversationController.getOrCreate(aci, 'private'); if ( !isMe(contact.attributes) && - member.profileKey && - member.profileKey.length > 0 && - contact.get('profileKey') !== member.profileKey + profileKey && + profileKey.length > 0 && + contact.get('profileKey') !== profileKey ) { contactsWithoutProfileKey.push(contact); - void contact.setProfileKey(member.profileKey); + drop(contact.setProfileKey(profileKey)); } - }); + } let profileFetches: Promise> | undefined; if (contactsWithoutProfileKey.length !== 0) { @@ -3119,7 +3135,12 @@ async function updateGroup( if (changeMessagesToSave.length > 0) { try { - await profileFetches; + if (contactsWithoutProfileKey && contactsWithoutProfileKey.length > 0) { + await Promise.race([profileFetches, sleep(30 * SECOND)]); + log.info( + `updateGroup/${logId}: timed out or finished fetching ${contactsWithoutProfileKey.length} profiles` + ); + } } catch (error) { log.error( `updateGroup/${logId}: failed to fetch missing profiles`, @@ -3148,8 +3169,7 @@ async function updateGroup( const justAdded = !wasMemberOrPending && isMemberOrPending; const addedBy = newAttributes.pendingMembersV2?.find( - item => - item.uuid === ourACI.toString() || item.uuid === ourPNI?.toString() + item => item.serviceId === ourAci || item.serviceId === ourPni )?.addedByUserId || newAttributes.addedBy; if (justAdded && addedBy) { @@ -3212,19 +3232,19 @@ export function _mergeGroupChangeMessages( return undefined; } - const { uuid } = secondDetail; - strictAssert(uuid, 'admin approval message should have uuid'); + const { aci } = secondDetail; + strictAssert(aci, 'admin approval message should have aci'); let updatedDetail; // Member was previously added and is now removed if ( !isApprovalPending && firstDetail.type === 'admin-approval-add-one' && - firstDetail.uuid === uuid + firstDetail.aci === aci ) { updatedDetail = { type: 'admin-approval-bounce' as const, - uuid, + aci, times: 1, isApprovalPending, }; @@ -3232,12 +3252,12 @@ export function _mergeGroupChangeMessages( // There is an existing bounce event - merge this one into it. } else if ( firstDetail.type === 'admin-approval-bounce' && - firstDetail.uuid === uuid && + firstDetail.aci === aci && firstDetail.isApprovalPending === !isApprovalPending ) { updatedDetail = { type: 'admin-approval-bounce' as const, - uuid, + aci, times: firstDetail.times + (isApprovalPending ? 0 : 1), isApprovalPending, }; @@ -3292,7 +3312,7 @@ async function appendChangeMessages( `appendChangeMessages/${logId}: processing ${messages.length} messages` ); - const ourACI = window.textsecure.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.textsecure.storage.user.getCheckedAci(); let lastMessage = await dataInterface.getLastConversationMessage({ conversationId: conversation.id, @@ -3331,7 +3351,7 @@ async function appendChangeMessages( log.info(`appendChangeMessages/${logId}: updating ${first.id}`); await dataInterface.saveMessage(first, { - ourUuid: ourACI.toString(), + ourAci, // We don't use forceSave here because this is an update of existing // message. @@ -3341,7 +3361,7 @@ async function appendChangeMessages( `appendChangeMessages/${logId}: saving ${rest.length} new messages` ); await dataInterface.saveMessages(rest, { - ourUuid: ourACI.toString(), + ourAci, forceSave: true, }); } else { @@ -3349,14 +3369,14 @@ async function appendChangeMessages( `appendChangeMessages/${logId}: saving ${mergedMessages.length} new messages` ); await dataInterface.saveMessages(mergedMessages, { - ourUuid: ourACI.toString(), + ourAci, forceSave: true, }); } let newMessages = 0; for (const changeMessage of mergedMessages) { - const existing = window.MessageController.getById(changeMessage.id); + const existing = window.MessageCache.__DEPRECATED$getById(changeMessage.id); // Update existing message if (existing) { @@ -3368,8 +3388,12 @@ async function appendChangeMessages( continue; } - const model = new window.Whisper.Message(changeMessage); - window.MessageController.register(model.id, model); + let model = new window.Whisper.Message(changeMessage); + model = window.MessageCache.__DEPRECATED$register( + model.id, + model, + 'appendChangeMessages' + ); conversation.trigger('newmessage', model); newMessages += 1; } @@ -3402,11 +3426,11 @@ async function getGroupUpdates({ const currentRevision = group.revision; const isFirstFetch = !isNumber(group.revision); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.storage.user.getCheckedAci(); const isInitialCreationMessage = isFirstFetch && newRevision === 0; const weAreAwaitingApproval = (group.pendingAdminApprovalV2 || []).find( - item => item.uuid === ourACI.toString() + item => item.aci === ourAci ); const isOneVersionUp = isNumber(currentRevision) && @@ -3430,9 +3454,13 @@ async function getGroupUpdates({ if (isChangeSupported) { if (!wrappedGroupChange.isTrusted) { strictAssert( - groupChange.serverSignature && groupChange.actions, + groupChange.serverSignature, 'Server signature must be present in untrusted group change' ); + strictAssert( + groupChange.actions, + 'Actions must be present in untrusted group change' + ); try { verifyNotarySignature( serverPublicParamsBase64, @@ -3448,7 +3476,7 @@ async function getGroupUpdates({ return { newAttributes: group, groupChangeMessages: [], - members: [], + newProfileKeys: new Map(), }; } } @@ -3542,7 +3570,7 @@ async function getGroupUpdates({ return { newAttributes: group, groupChangeMessages: [], - members: [], + newProfileKeys: new Map(), }; } @@ -3552,9 +3580,7 @@ async function updateGroupViaPreJoinInfo({ group: ConversationAttributesType; }): Promise { const logId = idForLogging(group.groupId); - const ourACI = window.textsecure.storage.user - .getCheckedUuid(UUIDKind.ACI) - .toString(); + const ourAci = window.textsecure.storage.user.getCheckedAci(); const { publicParams, secretParams } = group; if (!secretParams) { @@ -3591,20 +3617,20 @@ async function updateGroupViaPreJoinInfo({ const newAttributes: ConversationAttributesType = { ...group, description: decryptGroupDescription( - preJoinInfo.descriptionBytes, + dropNull(preJoinInfo.descriptionBytes), secretParams ), - name: decryptGroupTitle(preJoinInfo.title, secretParams), + name: decryptGroupTitle(dropNull(preJoinInfo.title), secretParams), left: true, members: group.members || [], pendingMembersV2: group.pendingMembersV2 || [], pendingAdminApprovalV2: [ { - uuid: ourACI, + aci: ourAci, timestamp: Date.now(), }, ], - revision: preJoinInfo.version, + revision: dropNull(preJoinInfo.version), temporaryMemberCount: preJoinInfo.memberCount || 1, }; @@ -3618,7 +3644,7 @@ async function updateGroupViaPreJoinInfo({ current: newAttributes, dropInitialJoinMessage: false, }), - members: [], + newProfileKeys: new Map(), }; } @@ -3668,7 +3694,7 @@ async function updateGroupViaState({ current: newAttributes, dropInitialJoinMessage, }), - members: profileKeysToMembers(newProfileKeys), + newProfileKeys: profileKeysToMap(newProfileKeys), }; } @@ -3702,7 +3728,7 @@ async function updateGroupViaSingleChange({ ); const { newAttributes, - members, + newProfileKeys, groupChangeMessages: catchupMessages, } = await updateGroupViaLogs({ group: singleChangeResult.newAttributes, @@ -3737,7 +3763,10 @@ async function updateGroupViaSingleChange({ // keep the final group attributes generated, as well as any new members. return { groupChangeMessages, - members: [...singleChangeResult.members, ...members], + newProfileKeys: new Map([ + ...singleChangeResult.newProfileKeys, + ...newProfileKeys, + ]), newAttributes, }; } @@ -3822,8 +3851,8 @@ async function generateLeftGroupChanges( ): Promise { const logId = idForLogging(group.groupId); log.info(`generateLeftGroupChanges/${logId}: Starting...`); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI).toString(); - const ourPNI = window.storage.user.getCheckedUuid(UUIDKind.PNI)?.toString(); + const ourAci = window.storage.user.getCheckedAci(); + const ourPni = window.storage.user.getCheckedPni(); const { masterKey, groupInviteLinkPassword } = group; let { revision } = group; @@ -3838,7 +3867,7 @@ async function generateLeftGroupChanges( masterKey ); - revision = preJoinInfo.version; + revision = dropNull(preJoinInfo.version); } } catch (error) { log.warn( @@ -3850,12 +3879,12 @@ async function generateLeftGroupChanges( const newAttributes: ConversationAttributesType = { ...group, addedBy: undefined, - membersV2: (group.membersV2 || []).filter(member => member.uuid !== ourACI), + membersV2: (group.membersV2 || []).filter(member => member.aci !== ourAci), pendingMembersV2: (group.pendingMembersV2 || []).filter( - member => member.uuid !== ourACI && member.uuid !== ourPNI + member => member.serviceId !== ourAci && member.serviceId !== ourPni ), pendingAdminApprovalV2: (group.pendingAdminApprovalV2 || []).filter( - member => member.uuid !== ourACI + member => member.aci !== ourAci ), left: true, revision, @@ -3867,7 +3896,7 @@ async function generateLeftGroupChanges( current: newAttributes, old: group, }), - members: [], + newProfileKeys: new Map(), }; } @@ -3910,7 +3939,7 @@ async function integrateGroupChanges({ const logId = idForLogging(group.groupId); let attributes = group; const finalMessages: Array> = []; - const finalMembers: Array> = []; + const finalNewProfileKeys = new Map(); const imax = changes.length; for (let i = 0; i < imax; i += 1) { @@ -3937,7 +3966,7 @@ async function integrateGroupChanges({ const { newAttributes, groupChangeMessages, - members, + newProfileKeys, // eslint-disable-next-line no-await-in-loop } = await integrateGroupChange({ group: attributes, @@ -3948,7 +3977,9 @@ async function integrateGroupChanges({ attributes = newAttributes; finalMessages.push(groupChangeMessages); - finalMembers.push(members); + for (const [aci, profileKey] of newProfileKeys) { + finalNewProfileKeys.set(aci, profileKey); + } } catch (error) { log.error( `integrateGroupChanges/${logId}: Failed to apply change log, continuing to apply remaining change logs.`, @@ -3981,14 +4012,14 @@ async function integrateGroupChanges({ return { newAttributes: attributes, groupChangeMessages, - members: flatten(finalMembers), + newProfileKeys: finalNewProfileKeys, }; } return { newAttributes: attributes, groupChangeMessages: flatten(finalMessages), - members: flatten(finalMembers), + newProfileKeys: finalNewProfileKeys, }; } @@ -4017,12 +4048,9 @@ async function integrateGroupChange({ } const isFirstFetch = !isNumber(group.revision); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); - const ourPNI = window.storage.user.getUuid(UUIDKind.PNI); + const ourAci = window.storage.user.getCheckedAci(); const weAreAwaitingApproval = (group.pendingAdminApprovalV2 || []).find( - item => - item.uuid === ourACI.toString() || - (ourPNI && item.uuid === ourPNI.toString()) + item => item.aci === ourAci ); // These need to be populated from the groupChange. But we might not get one! @@ -4031,7 +4059,7 @@ async function integrateGroupChange({ let isMoreThanOneVersionUp = false; let groupChangeActions: undefined | Proto.GroupChange.IActions; let decryptedChangeActions: undefined | DecryptedGroupChangeActions; - let sourceUuid: undefined | UUIDStringType; + let sourceServiceId: undefined | ServiceIdString; if (groupChange) { groupChangeActions = Proto.GroupChange.Actions.decode( @@ -4051,7 +4079,7 @@ async function integrateGroupChange({ return { newAttributes: group, groupChangeMessages: [], - members: [], + newProfileKeys: new Map(), }; } @@ -4065,8 +4093,8 @@ async function integrateGroupChange({ decryptedChangeActions !== undefined, 'Should have decrypted group actions' ); - ({ sourceUuid } = decryptedChangeActions); - strictAssert(sourceUuid, 'Should have source UUID'); + ({ sourceServiceId } = decryptedChangeActions); + strictAssert(sourceServiceId, 'Should have source service id'); isChangeSupported = !isNumber(groupChange.changeEpoch) || @@ -4083,7 +4111,7 @@ async function integrateGroupChange({ return { newAttributes: group, groupChangeMessages: [], - members: [], + newProfileKeys: new Map(), }; } if (groupChangeActions.version === group.revision) { @@ -4099,7 +4127,7 @@ async function integrateGroupChange({ let attributes = group; const aggregatedChangeMessages = []; - const aggregatedMembers = []; + const finalNewProfileKeys = new Map(); const canApplyChange = groupChange && @@ -4110,7 +4138,7 @@ async function integrateGroupChange({ // Apply the change first if (canApplyChange) { - if (!sourceUuid || !groupChangeActions || !decryptedChangeActions) { + if (!sourceServiceId || !groupChangeActions || !decryptedChangeActions) { throw new Error( `integrateGroupChange/${logId}: Missing necessary information that should have come from group actions` ); @@ -4125,19 +4153,21 @@ async function integrateGroupChange({ await applyGroupChange({ group, actions: decryptedChangeActions, - sourceUuid, + sourceServiceId, }); const groupChangeMessages = extractDiffs({ old: attributes, current: newAttributes, - sourceUuid, + sourceServiceId, promotedAciToPniMap, }); attributes = newAttributes; aggregatedChangeMessages.push(groupChangeMessages); - aggregatedMembers.push(profileKeysToMembers(newProfileKeys)); + for (const [aci, profileKey] of profileKeysToMap(newProfileKeys)) { + finalNewProfileKeys.set(aci, profileKey); + } } // Apply the group state afterwards to verify that we didn't miss anything @@ -4161,25 +4191,28 @@ async function integrateGroupChange({ logId ); - const { newAttributes, newProfileKeys, otherChanges } = - await applyGroupState({ - group: attributes, - groupState: decryptedGroupState, - sourceUuid: isFirstFetch ? sourceUuid : undefined, - }); + const { + newAttributes, + newProfileKeys: newProfileKeysList, + otherChanges, + } = await applyGroupState({ + group: attributes, + groupState: decryptedGroupState, + sourceServiceId: isFirstFetch ? sourceServiceId : undefined, + }); const groupChangeMessages = extractDiffs({ old: attributes, current: newAttributes, - sourceUuid: isFirstFetch ? sourceUuid : undefined, + sourceServiceId: isFirstFetch ? sourceServiceId : undefined, }); - const newMembers = profileKeysToMembers(newProfileKeys); + const newProfileKeys = profileKeysToMap(newProfileKeysList); if ( canApplyChange && (groupChangeMessages.length !== 0 || - newMembers.length !== 0 || + newProfileKeys.size !== 0 || otherChanges) ) { assertDev( @@ -4191,14 +4224,16 @@ async function integrateGroupChange({ `integrateGroupChange/${logId}: local state was different from ` + 'the remote final state. ' + `Got ${groupChangeMessages.length} change messages, ` + - `${newMembers.length} updated members, and ` + + `${newProfileKeys.size} updated members, and ` + `otherChanges=${otherChanges}` ); } attributes = newAttributes; aggregatedChangeMessages.push(groupChangeMessages); - aggregatedMembers.push(newMembers); + for (const [aci, profileKey] of newProfileKeys) { + finalNewProfileKeys.set(aci, profileKey); + } } else { strictAssert( canApplyChange, @@ -4209,7 +4244,7 @@ async function integrateGroupChange({ return { newAttributes: attributes, groupChangeMessages: aggregatedChangeMessages.flat(), - members: aggregatedMembers.flat(), + newProfileKeys: finalNewProfileKeys, }; } @@ -4217,38 +4252,38 @@ function extractDiffs({ current, dropInitialJoinMessage, old, - sourceUuid, + sourceServiceId, promotedAciToPniMap, }: { current: ConversationAttributesType; dropInitialJoinMessage?: boolean; old: ConversationAttributesType; - sourceUuid?: UUIDStringType; - promotedAciToPniMap?: ReadonlyMap; + sourceServiceId?: ServiceIdString; + promotedAciToPniMap?: ReadonlyMap; }): Array { const logId = idForLogging(old.groupId); const details: Array = []; - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); - const ourPNI = window.storage.user.getUuid(UUIDKind.PNI); + const ourAci = window.storage.user.getCheckedAci(); + const ourPni = window.storage.user.getPni(); const ACCESS_ENUM = Proto.AccessControl.AccessRequired; let areWeInGroup = false; - let uuidKindInvitedToGroup: UUIDKind | undefined; + let serviceIdKindInvitedToGroup: ServiceIdKind | undefined; let areWePendingApproval = false; let whoInvitedUsUserId = null; - function isUs(uuid: UUIDStringType): boolean { - return uuid === ourACI.toString() || uuid === ourPNI?.toString(); + function isUs(serviceId: ServiceIdString): boolean { + return serviceId === ourAci || serviceId === ourPni; } function keepOnlyOurAdds( list: Array ): Array { return list.filter( item => - (item.type === 'member-add-from-invite' && isUs(item.uuid)) || - (item.type === 'member-add-from-link' && isUs(item.uuid)) || - (item.type === 'member-add-from-admin-approval' && isUs(item.uuid)) || - (item.type === 'member-add' && isUs(item.uuid)) + (item.type === 'member-add-from-invite' && isUs(item.aci)) || + (item.type === 'member-add-from-link' && isUs(item.aci)) || + (item.type === 'member-add-from-admin-approval' && isUs(item.aci)) || + (item.type === 'member-add' && isUs(item.aci)) ); } @@ -4353,47 +4388,45 @@ function extractDiffs({ // membersV2 - const oldMemberLookup = new Map( - (old.membersV2 || []).map(member => [member.uuid, member]) + const oldMemberLookup = new Map( + (old.membersV2 || []).map(member => [member.aci, member]) ); - const didWeStartInGroup = - (ourACI && oldMemberLookup.get(ourACI.toString())) || - (ourPNI && oldMemberLookup.get(ourPNI.toString())); + const didWeStartInGroup = Boolean(ourAci && oldMemberLookup.has(ourAci)); const oldPendingMemberLookup = new Map< - UUIDStringType, + ServiceIdString, GroupV2PendingMemberType - >((old.pendingMembersV2 || []).map(member => [member.uuid, member])); + >((old.pendingMembersV2 || []).map(member => [member.serviceId, member])); const oldPendingAdminApprovalLookup = new Map< - UUIDStringType, + AciString, GroupV2PendingAdminApprovalType - >((old.pendingAdminApprovalV2 || []).map(member => [member.uuid, member])); - const currentPendingMemberSet = new Set( - (current.pendingMembersV2 || []).map(member => member.uuid) + >((old.pendingAdminApprovalV2 || []).map(member => [member.aci, member])); + const currentPendingMemberSet = new Set( + (current.pendingMembersV2 || []).map(member => member.serviceId) ); const aciToPniMap = new Map(promotedAciToPniMap?.entries()); - if (ourACI && ourPNI) { - aciToPniMap.set(ourACI.toString(), ourPNI.toString()); + if (ourAci && ourPni) { + aciToPniMap.set(ourAci, ourPni); } - const pniToAciMap = new Map(); + const pniToAciMap = new Map(); for (const [aci, pni] of aciToPniMap) { pniToAciMap.set(pni, aci); } (current.membersV2 || []).forEach(currentMember => { - const { uuid } = currentMember; - const uuidIsUs = isUs(uuid); + const { aci } = currentMember; + const uuidIsUs = isUs(aci); if (uuidIsUs) { areWeInGroup = true; } - const oldMember = oldMemberLookup.get(uuid); + const oldMember = oldMemberLookup.get(aci); if (!oldMember) { - let pendingMember = oldPendingMemberLookup.get(uuid); - const pni = aciToPniMap.get(uuid); + let pendingMember = oldPendingMemberLookup.get(aci); + const pni = aciToPniMap.get(aci); if (!pendingMember && pni) { pendingMember = oldPendingMemberLookup.get(pni); @@ -4409,29 +4442,29 @@ function extractDiffs({ if (pendingMember) { details.push({ type: 'member-add-from-invite', - uuid, + aci, inviter: pendingMember.addedByUserId, }); } else if (currentMember.joinedFromLink) { details.push({ type: 'member-add-from-link', - uuid, + aci, }); } else if (currentMember.approvedByAdmin) { details.push({ type: 'member-add-from-admin-approval', - uuid, + aci, }); } else { details.push({ type: 'member-add', - uuid, + aci, }); } } else if (oldMember.role !== currentMember.role) { details.push({ type: 'member-privilege', - uuid, + aci, newPrivilege: currentMember.role, }); } @@ -4439,49 +4472,49 @@ function extractDiffs({ // We don't want to generate an admin-approval-remove event for this newly-added // member. But we don't know for sure if this is an admin approval; for that we // consulted the approvedByAdmin flag saved on the member. - oldPendingAdminApprovalLookup.delete(uuid); + oldPendingAdminApprovalLookup.delete(aci); // If we capture a pending remove here, it's an 'accept invitation', and we don't // want to generate a pending-remove event for it - oldPendingMemberLookup.delete(uuid); + oldPendingMemberLookup.delete(aci); // This deletion makes it easier to capture removals - oldMemberLookup.delete(uuid); + oldMemberLookup.delete(aci); }); const removedMemberIds = Array.from(oldMemberLookup.keys()); - removedMemberIds.forEach(uuid => { + removedMemberIds.forEach(aci => { details.push({ type: 'member-remove', - uuid, + aci, }); }); // pendingMembersV2 - let lastPendingUuid: UUIDStringType | undefined; + let lastPendingServiceId: ServiceIdString | undefined; let pendingCount = 0; (current.pendingMembersV2 || []).forEach(currentPendingMember => { - const { uuid } = currentPendingMember; - const oldPendingMember = oldPendingMemberLookup.get(uuid); + const { serviceId } = currentPendingMember; + const oldPendingMember = oldPendingMemberLookup.get(serviceId); - if (isUs(uuid)) { - if (uuid === ourACI.toString()) { - uuidKindInvitedToGroup = UUIDKind.ACI; - } else if (uuidKindInvitedToGroup === undefined) { - uuidKindInvitedToGroup = UUIDKind.PNI; + if (isUs(serviceId)) { + if (serviceId === ourAci) { + serviceIdKindInvitedToGroup = ServiceIdKind.ACI; + } else if (serviceIdKindInvitedToGroup === undefined) { + serviceIdKindInvitedToGroup = ServiceIdKind.PNI; } whoInvitedUsUserId = currentPendingMember.addedByUserId; } if (!oldPendingMember) { - lastPendingUuid = uuid; + lastPendingServiceId = serviceId; pendingCount += 1; } // This deletion makes it easier to capture removals - oldPendingMemberLookup.delete(uuid); + oldPendingMemberLookup.delete(serviceId); }); if (pendingCount > 1) { @@ -4490,10 +4523,10 @@ function extractDiffs({ count: pendingCount, }); } else if (pendingCount === 1) { - if (lastPendingUuid) { + if (lastPendingServiceId) { details.push({ type: 'pending-add-one', - uuid: lastPendingUuid, + serviceId: lastPendingServiceId, }); } else { log.warn( @@ -4522,13 +4555,13 @@ function extractDiffs({ inviter: allSameInviter ? inviter : undefined, }); } else if (removedPendingMemberIds.length === 1) { - const uuid = removedPendingMemberIds[0]; - const removedMember = oldPendingMemberLookup.get(uuid); + const serviceId = removedPendingMemberIds[0]; + const removedMember = oldPendingMemberLookup.get(serviceId); strictAssert(removedMember !== undefined, 'Removed member not found'); details.push({ type: 'pending-remove-one', - uuid, + serviceId, inviter: removedMember.addedByUserId, }); } @@ -4537,22 +4570,22 @@ function extractDiffs({ (current.pendingAdminApprovalV2 || []).forEach( currentPendingAdminAprovalMember => { - const { uuid } = currentPendingAdminAprovalMember; - const oldPendingMember = oldPendingAdminApprovalLookup.get(uuid); + const { aci } = currentPendingAdminAprovalMember; + const oldPendingMember = oldPendingAdminApprovalLookup.get(aci); - if (uuid === ourACI.toString()) { + if (aci === ourAci) { areWePendingApproval = true; } if (!oldPendingMember) { details.push({ type: 'admin-approval-add-one', - uuid, + aci, }); } // This deletion makes it easier to capture removals - oldPendingAdminApprovalLookup.delete(uuid); + oldPendingAdminApprovalLookup.delete(aci); } ); @@ -4561,10 +4594,10 @@ function extractDiffs({ const removedPendingAdminApprovalIds = Array.from( oldPendingAdminApprovalLookup.keys() ); - removedPendingAdminApprovalIds.forEach(uuid => { + removedPendingAdminApprovalIds.forEach(aci => { details.push({ type: 'admin-approval-remove-one', - uuid, + aci, }); }); @@ -4585,15 +4618,19 @@ function extractDiffs({ let timerNotification: GroupChangeMessageType | undefined; const firstUpdate = !isNumber(old.revision); - const isFromUs = ourACI.toString() === sourceUuid; + const isFromUs = ourAci === sourceServiceId; const justJoinedGroup = !firstUpdate && !didWeStartInGroup && areWeInGroup; - const from = (sourceUuid && pniToAciMap.get(sourceUuid)) ?? sourceUuid; + const from = + (sourceServiceId && + isPniString(sourceServiceId) && + pniToAciMap.get(sourceServiceId)) || + sourceServiceId; // Here we hardcode initial messages if this is our first time processing data for this // group. Ideally we can collapse it down to just one of: 'you were added', // 'you were invited', or 'you created.' - if (firstUpdate && uuidKindInvitedToGroup !== undefined) { + if (firstUpdate && serviceIdKindInvitedToGroup !== undefined) { // Note, we will add 'you were invited' to group even if dropInitialJoinMessage = true message = { ...generateBasicMessage(), @@ -4603,9 +4640,9 @@ function extractDiffs({ details: [ { type: 'pending-add-one', - uuid: window.storage.user - .getCheckedUuid(uuidKindInvitedToGroup) - .toString(), + serviceId: window.storage.user.getCheckedServiceId( + serviceIdKindInvitedToGroup + ), }, ], }, @@ -4617,11 +4654,11 @@ function extractDiffs({ ...generateBasicMessage(), type: 'group-v2-change', groupV2Change: { - from: ourACI.toString(), + from: ourAci, details: [ { type: 'admin-approval-add-one', - uuid: ourACI.toString(), + aci: ourAci, }, ], }, @@ -4632,7 +4669,7 @@ function extractDiffs({ } else if ( firstUpdate && current.revision === 0 && - sourceUuid === ourACI.toString() + sourceServiceId === ourAci ) { message = { ...generateBasicMessage(), @@ -4699,7 +4736,7 @@ function extractDiffs({ message = { ...generateBasicMessage(), type: 'group-v2-change', - sourceUuid, + sourceServiceId, groupV2Change: { from, details: filteredDetails, @@ -4711,7 +4748,7 @@ function extractDiffs({ message = { ...generateBasicMessage(), type: 'group-v2-change', - sourceUuid, + sourceServiceId, groupV2Change: { from, details, @@ -4738,11 +4775,11 @@ function extractDiffs({ timerNotification = { ...generateBasicMessage(), type: 'timer-notification', - sourceUuid, + sourceServiceId, flags: Proto.DataMessage.Flags.EXPIRATION_TIMER_UPDATE, expirationTimerUpdate: { expireTimer, - sourceUuid, + sourceServiceId, }, }; } @@ -4756,16 +4793,17 @@ function extractDiffs({ return result; } -function profileKeysToMembers(items: ReadonlyArray) { - return items.map(item => ({ - profileKey: Bytes.toBase64(item.profileKey), - uuid: item.uuid, - })); +function profileKeysToMap(items: ReadonlyArray) { + const map = new Map(); + for (const { aci, profileKey } of items) { + map.set(aci, Bytes.toBase64(profileKey)); + } + return map; } type GroupChangeMemberType = { profileKey: Uint8Array; - uuid: UUIDStringType; + aci: AciString; }; type GroupApplyResultType = { newAttributes: ConversationAttributesType; @@ -4774,20 +4812,20 @@ type GroupApplyResultType = { }; type GroupApplyChangeResultType = GroupApplyResultType & { - promotedAciToPniMap: Map; + promotedAciToPniMap: Map; }; async function applyGroupChange({ actions, group, - sourceUuid, + sourceServiceId, }: { actions: DecryptedGroupChangeActions; group: ConversationAttributesType; - sourceUuid: UUIDStringType; + sourceServiceId: ServiceIdString; }): Promise { const logId = idForLogging(group.groupId); - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI).toString(); + const ourAci = window.storage.user.getCheckedAci(); const ACCESS_ENUM = Proto.AccessControl.AccessRequired; const MEMBER_ROLE_ENUM = Proto.Member.Role; @@ -4795,23 +4833,23 @@ async function applyGroupChange({ const version = actions.version || 0; const result = { ...group }; const newProfileKeys: Array = []; - const promotedAciToPniMap = new Map(); + const promotedAciToPniMap = new Map(); - const members: Record = fromPairs( - (result.membersV2 || []).map(member => [member.uuid, member]) + const members: Record = fromPairs( + (result.membersV2 || []).map(member => [member.aci, member]) ); - const pendingMembers: Record = + const pendingMembers: Record = fromPairs( - (result.pendingMembersV2 || []).map(member => [member.uuid, member]) + (result.pendingMembersV2 || []).map(member => [member.serviceId, member]) ); const pendingAdminApprovalMembers: Record< - UUIDStringType, + AciString, GroupV2PendingAdminApprovalType > = fromPairs( - (result.pendingAdminApprovalV2 || []).map(member => [member.uuid, member]) + (result.pendingAdminApprovalV2 || []).map(member => [member.aci, member]) ); - const bannedMembers = new Map( - (result.bannedMembersV2 || []).map(member => [member.uuid, member]) + const bannedMembers = new Map( + (result.bannedMembersV2 || []).map(member => [member.serviceId, member]) ); if (result.temporaryMemberCount) { @@ -4830,7 +4868,7 @@ async function applyGroupChange({ throw new Error('applyGroupChange: addMember.added is missing'); } - const addedUuid = UUID.cast(added.userId); + const addedUuid = added.userId; if (members[addedUuid]) { log.warn( @@ -4840,7 +4878,7 @@ async function applyGroupChange({ } members[addedUuid] = { - uuid: addedUuid, + aci: addedUuid, role: added.role || MEMBER_ROLE_ENUM.DEFAULT, joinedAtVersion: version, joinedFromLink: addMember.joinFromInviteLink || false, @@ -4854,14 +4892,14 @@ async function applyGroupChange({ } // Capture who added us - if (ourACI && sourceUuid && addedUuid === ourACI) { - result.addedBy = sourceUuid; + if (ourAci && sourceServiceId && addedUuid === ourAci) { + result.addedBy = sourceServiceId; } if (added.profileKey) { newProfileKeys.push({ profileKey: added.profileKey, - uuid: UUID.cast(added.userId), + aci: added.userId, }); } }); @@ -4875,9 +4913,8 @@ async function applyGroupChange({ ); } - const deletedUuid = UUID.cast(deletedUserId); - if (members[deletedUuid]) { - delete members[deletedUuid]; + if (members[deletedUserId]) { + delete members[deletedUserId]; } else { log.warn( `applyGroupChange/${logId}: Attempt to remove member failed; was not in members.` @@ -4892,10 +4929,9 @@ async function applyGroupChange({ throw new Error('applyGroupChange: modifyMemberRole had a missing value'); } - const userUuid = UUID.cast(userId); - if (members[userUuid]) { - members[userUuid] = { - ...members[userUuid], + if (members[userId]) { + members[userId] = { + ...members[userId], role, }; } else { @@ -4908,17 +4944,24 @@ async function applyGroupChange({ // modifyMemberProfileKeys?: // Array; (actions.modifyMemberProfileKeys || []).forEach(modifyMemberProfileKey => { - const { profileKey, uuid } = modifyMemberProfileKey; - if (!profileKey || !uuid) { + const { profileKey, aci } = modifyMemberProfileKey; + if (!profileKey || !aci) { throw new Error( 'applyGroupChange: modifyMemberProfileKey had a missing value' ); } - newProfileKeys.push({ - profileKey, - uuid: UUID.cast(uuid), - }); + if (aci === sourceServiceId || !hasProfileKey(aci)) { + newProfileKeys.push({ + profileKey, + aci, + }); + } else { + log.warn( + `applyGroupChange/${logId}: Attempt to modify member profile key ` + + 'failed; sourceServiceId is not the same as change aci' + ); + } }); // addPendingMembers?: Array< @@ -4932,24 +4975,24 @@ async function applyGroupChange({ ); } - const addedUuid = UUID.cast(added.member.userId); + const addedUserId = added.member.userId; - if (members[addedUuid]) { + if (isAciString(addedUserId) && members[addedUserId]) { log.warn( `applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in members.` ); return; } - if (pendingMembers[addedUuid]) { + if (pendingMembers[addedUserId]) { log.warn( `applyGroupChange/${logId}: Attempt to add pendingMember failed; was already in pendingMembers.` ); return; } - pendingMembers[addedUuid] = { - uuid: addedUuid, - addedByUserId: UUID.cast(added.addedByUserId), + pendingMembers[addedUserId] = { + serviceId: addedUserId, + addedByUserId: added.addedByUserId, timestamp: added.timestamp, role: added.member.role || MEMBER_ROLE_ENUM.DEFAULT, }; @@ -4966,10 +5009,8 @@ async function applyGroupChange({ ); } - const deletedUuid = UUID.cast(deletedUserId); - - if (pendingMembers[deletedUuid]) { - delete pendingMembers[deletedUuid]; + if (pendingMembers[deletedUserId]) { + delete pendingMembers[deletedUserId]; } else { log.warn( `applyGroupChange/${logId}: Attempt to remove pendingMember failed; was not in pendingMembers.` @@ -4981,40 +5022,39 @@ async function applyGroupChange({ // GroupChange.Actions.PromoteMemberPendingProfileKeyAction // >; (actions.promotePendingMembers || []).forEach(promotePendingMember => { - const { profileKey, uuid: rawUuid } = promotePendingMember; - if (!profileKey || !rawUuid) { + const { profileKey, aci } = promotePendingMember; + if (!profileKey || !aci) { throw new Error( 'applyGroupChange: promotePendingMember had a missing value' ); } - const uuid = UUID.cast(rawUuid); - const previousRecord = pendingMembers[uuid]; + const previousRecord = pendingMembers[aci]; - if (pendingMembers[uuid]) { - delete pendingMembers[uuid]; + if (pendingMembers[aci]) { + delete pendingMembers[aci]; } else { log.warn( `applyGroupChange/${logId}: Attempt to promote pendingMember failed; was not in pendingMembers.` ); } - if (members[uuid]) { + if (members[aci]) { log.warn( `applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.` ); return; } - members[uuid] = { - uuid, + members[aci] = { + aci, joinedAtVersion: version, role: previousRecord.role || MEMBER_ROLE_ENUM.DEFAULT, }; newProfileKeys.push({ profileKey, - uuid, + aci, }); }); @@ -5050,14 +5090,14 @@ async function applyGroupChange({ } members[aci] = { - uuid: aci, + aci, joinedAtVersion: version, role: previousRecord.role || MEMBER_ROLE_ENUM.DEFAULT, }; newProfileKeys.push({ profileKey, - uuid: aci, + aci, }); } ); @@ -5147,36 +5187,35 @@ async function applyGroupChange({ 'applyGroupChange: modifyMemberProfileKey had a missing value' ); } - const addedUuid = UUID.cast(added.userId); - if (members[addedUuid]) { + if (members[added.userId]) { log.warn( `applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in members.` ); return; } - if (pendingMembers[addedUuid]) { + if (pendingMembers[added.userId]) { log.warn( `applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingMembers.` ); return; } - if (pendingAdminApprovalMembers[addedUuid]) { + if (pendingAdminApprovalMembers[added.userId]) { log.warn( `applyGroupChange/${logId}: Attempt to add pending admin approval failed; was already in pendingAdminApprovalMembers.` ); return; } - pendingAdminApprovalMembers[addedUuid] = { - uuid: addedUuid, + pendingAdminApprovalMembers[added.userId] = { + aci: added.userId, timestamp: added.timestamp, }; if (added.profileKey) { newProfileKeys.push({ profileKey: added.profileKey, - uuid: addedUuid, + aci: added.userId, }); } } @@ -5194,10 +5233,8 @@ async function applyGroupChange({ ); } - const deletedUuid = UUID.cast(deletedUserId); - - if (pendingAdminApprovalMembers[deletedUuid]) { - delete pendingAdminApprovalMembers[deletedUuid]; + if (pendingAdminApprovalMembers[deletedUserId]) { + delete pendingAdminApprovalMembers[deletedUserId]; } else { log.warn( `applyGroupChange/${logId}: Attempt to remove pendingAdminApproval failed; was not in pendingAdminApprovalMembers.` @@ -5218,31 +5255,29 @@ async function applyGroupChange({ ); } - const userUuid = UUID.cast(userId); - - if (pendingAdminApprovalMembers[userUuid]) { - delete pendingAdminApprovalMembers[userUuid]; + if (pendingAdminApprovalMembers[userId]) { + delete pendingAdminApprovalMembers[userId]; } else { log.warn( `applyGroupChange/${logId}: Attempt to promote pendingAdminApproval failed; was not in pendingAdminApprovalMembers.` ); } - if (pendingMembers[userUuid]) { - delete pendingAdminApprovalMembers[userUuid]; + if (pendingMembers[userId]) { + delete pendingAdminApprovalMembers[userId]; log.warn( `applyGroupChange/${logId}: Deleted pendingAdminApproval from pendingMembers.` ); } - if (members[userUuid]) { + if (members[userId]) { log.warn( `applyGroupChange/${logId}: Attempt to promote pendingMember failed; was already in members.` ); return; } - members[userUuid] = { - uuid: userUuid, + members[userId] = { + aci: userId, joinedAtVersion: version, role: role || MEMBER_ROLE_ENUM.DEFAULT, approvedByAdmin: true, @@ -5280,32 +5315,32 @@ async function applyGroupChange({ if (actions.addMembersBanned && actions.addMembersBanned.length > 0) { actions.addMembersBanned.forEach(member => { - if (bannedMembers.has(member.uuid)) { + if (bannedMembers.has(member.serviceId)) { log.warn( `applyGroupChange/${logId}: Attempt to add banned member failed; was already in banned list.` ); return; } - bannedMembers.set(member.uuid, member); + bannedMembers.set(member.serviceId, member); }); } if (actions.deleteMembersBanned && actions.deleteMembersBanned.length > 0) { - actions.deleteMembersBanned.forEach(uuid => { - if (!bannedMembers.has(uuid)) { + actions.deleteMembersBanned.forEach(serviceId => { + if (!bannedMembers.has(serviceId)) { log.warn( `applyGroupChange/${logId}: Attempt to remove banned member failed; was not in banned list.` ); return; } - bannedMembers.delete(uuid); + bannedMembers.delete(serviceId); }); } - if (ourACI) { - result.left = !members[ourACI]; + if (ourAci) { + result.left = !members[ourAci]; } if (result.left) { result.addedBy = undefined; @@ -5412,7 +5447,10 @@ export async function applyNewAvatar( } /* eslint-enable no-param-reassign */ -function profileKeyHasChanged(userId: string, newProfileKey: Uint8Array) { +function profileKeyHasChanged( + userId: ServiceIdString, + newProfileKey: Uint8Array +) { const conversation = window.ConversationController.get(userId); if (!conversation) { return true; @@ -5428,14 +5466,24 @@ function profileKeyHasChanged(userId: string, newProfileKey: Uint8Array) { return newBase64 !== existingBase64; } +function hasProfileKey(userId: ServiceIdString) { + const conversation = window.ConversationController.get(userId); + if (!conversation) { + return false; + } + + const existingBase64 = conversation.get('profileKey'); + return existingBase64 !== undefined; +} + async function applyGroupState({ group, groupState, - sourceUuid, + sourceServiceId, }: { group: ConversationAttributesType; groupState: DecryptedGroupState; - sourceUuid?: UUIDStringType; + sourceServiceId?: ServiceIdString; }): Promise { const logId = idForLogging(group.groupId); const ACCESS_ENUM = Proto.AccessControl.AccessRequired; @@ -5449,19 +5497,19 @@ async function applyGroupState({ // Used to detect changes in these lists const members: Record = fromPairs( - (result.membersV2 || []).map(member => [member.uuid, member]) + (result.membersV2 || []).map(member => [member.aci, member]) ); const pendingMembers: Record = fromPairs( - (result.pendingMembersV2 || []).map(member => [member.uuid, member]) + (result.pendingMembersV2 || []).map(member => [member.serviceId, member]) ); const pendingAdminApprovalMembers: Record< string, GroupV2PendingAdminApprovalType > = fromPairs( - (result.pendingAdminApprovalV2 || []).map(member => [member.uuid, member]) + (result.pendingAdminApprovalV2 || []).map(member => [member.aci, member]) ); const bannedMembers = new Map( - (result.bannedMembersV2 || []).map(member => [member.uuid, member]) + (result.bannedMembersV2 || []).map(member => [member.serviceId, member]) ); // version @@ -5506,25 +5554,25 @@ async function applyGroupState({ // Optimization: we assume we have left the group unless we are found in members result.left = true; - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI).toString(); + const ourAci = window.storage.user.getCheckedAci(); // members const wasPreviouslyAMember = (result.membersV2 || []).some( - item => item.uuid !== ourACI + item => item.aci !== ourAci ); if (groupState.members) { result.membersV2 = groupState.members.map(member => { - if (member.userId === ourACI) { + if (member.userId === ourAci) { result.left = false; // Capture who added us if we were previously not in group if ( - sourceUuid && + sourceServiceId && !wasPreviouslyAMember && isNumber(member.joinedAtVersion) && member.joinedAtVersion === version ) { - result.addedBy = sourceUuid; + result.addedBy = sourceServiceId; } } @@ -5535,15 +5583,19 @@ async function applyGroupState({ } const previousMember = members[member.userId]; - if ( - member.profileKey && - (!previousMember || - profileKeyHasChanged(member.userId, member.profileKey)) - ) { + if (member.profileKey && !hasProfileKey(member.userId)) { newProfileKeys.push({ profileKey: member.profileKey, - uuid: UUID.cast(member.userId), + aci: member.userId, }); + } else if ( + member.profileKey && + profileKeyHasChanged(member.userId, member.profileKey) + ) { + log.warn( + `applyGroupState(${logId}): Member ${member.userId} had different profileKey` + ); + otherChanges = true; } else if (!previousMember) { otherChanges = true; } @@ -5561,8 +5613,8 @@ async function applyGroupState({ return { role: member.role || MEMBER_ROLE_ENUM.DEFAULT, - joinedAtVersion: member.joinedAtVersion || version, - uuid: UUID.cast(member.userId), + joinedAtVersion: member.joinedAtVersion, + aci: member.userId, }; }); } @@ -5615,8 +5667,8 @@ async function applyGroupState({ } return { - addedByUserId: UUID.cast(member.addedByUserId), - uuid: UUID.cast(member.member.userId), + addedByUserId: member.addedByUserId, + serviceId: member.member.userId, timestamp: member.timestamp, role: member.member.role || MEMBER_ROLE_ENUM.DEFAULT, }; @@ -5629,15 +5681,19 @@ async function applyGroupState({ result.pendingAdminApprovalV2 = groupState.membersPendingAdminApproval.map( member => { const previousMember = pendingAdminApprovalMembers[member.userId]; - if ( - member.profileKey && - (!previousMember || - profileKeyHasChanged(member.userId, member.profileKey)) - ) { + if (member.profileKey && !hasProfileKey(member.userId)) { newProfileKeys.push({ profileKey: member.profileKey, - uuid: UUID.cast(member.userId), + aci: member.userId, }); + } else if ( + member.profileKey && + profileKeyHasChanged(member.userId, member.profileKey) + ) { + log.warn( + `applyGroupState(${logId}): Member ${member.userId} had different profileKey` + ); + otherChanges = true; } else if (!previousMember) { otherChanges = true; } @@ -5650,7 +5706,7 @@ async function applyGroupState({ } return { - uuid: UUID.cast(member.userId), + aci: member.userId, timestamp: member.timestamp, }; } @@ -5678,14 +5734,14 @@ async function applyGroupState({ // membersBanned result.bannedMembersV2 = groupState.membersBanned?.map(member => { - const previousMember = bannedMembers.get(member.uuid); + const previousMember = bannedMembers.get(member.serviceId); if (!previousMember) { otherChanges = true; } if (previousMember && previousMember.timestamp !== member.timestamp) { otherChanges = true; log.warn( - `applyGroupState(${logId}): Member ${member.uuid} had different timestamp` + `applyGroupState(${logId}): Member ${member.serviceId} had different timestamp` ); } @@ -5754,36 +5810,37 @@ function normalizeTimestamp(timestamp: Long | null | undefined): number { type DecryptedGroupChangeActions = { version?: number; - sourceUuid?: UUIDStringType; + sourceServiceId?: ServiceIdString; addMembers?: ReadonlyArray<{ added: DecryptedMember; joinFromInviteLink: boolean; }>; deleteMembers?: ReadonlyArray<{ - deletedUserId: string; + deletedUserId: AciString; }>; modifyMemberRoles?: ReadonlyArray<{ - userId: string; + userId: AciString; role: Proto.Member.Role; }>; modifyMemberProfileKeys?: ReadonlyArray<{ profileKey: Uint8Array; - uuid: UUIDStringType; + aci: AciString; }>; addPendingMembers?: ReadonlyArray<{ added: DecryptedMemberPendingProfileKey; }>; deletePendingMembers?: ReadonlyArray<{ - deletedUserId: string; + // This might be a PNI + deletedUserId: ServiceIdString; }>; promotePendingMembers?: ReadonlyArray<{ profileKey: Uint8Array; - uuid: UUIDStringType; + aci: AciString; }>; promoteMembersPendingPniAciProfileKey?: ReadonlyArray<{ profileKey: Uint8Array; - aci: UUIDStringType; - pni: UUIDStringType; + aci: AciString; + pni: PniString; }>; modifyTitle?: { title?: Proto.GroupAttributeBlob; @@ -5795,10 +5852,10 @@ type DecryptedGroupChangeActions = { added: DecryptedMemberPendingAdminApproval; }>; deleteMemberPendingAdminApprovals?: ReadonlyArray<{ - deletedUserId: string; + deletedUserId: AciString; }>; promoteMemberPendingAdminApprovals?: ReadonlyArray<{ - userId: string; + userId: AciString; role: Proto.Member.Role; }>; modifyInviteLinkPassword?: { @@ -5811,7 +5868,8 @@ type DecryptedGroupChangeActions = { announcementsOnly: boolean; }; addMembersBanned?: ReadonlyArray; - deleteMembersBanned?: ReadonlyArray; + // This might be a PNI + deleteMembersBanned?: ReadonlyArray; } & Pick< Proto.GroupChange.IActions, | 'modifyAttributesAccess' @@ -5831,29 +5889,27 @@ function decryptGroupChange( const clientZkGroupCipher = getClientZkGroupCipher(groupSecretParams); - if (actions.sourceUuid && actions.sourceUuid.length !== 0) { + if (actions.sourceUserId && actions.sourceUserId.length !== 0) { try { - result.sourceUuid = UUID.cast( - normalizeUuid( - decryptUuid(clientZkGroupCipher, actions.sourceUuid), - 'actions.sourceUuid' - ) + result.sourceServiceId = decryptServiceId( + clientZkGroupCipher, + actions.sourceUserId ); } catch (error) { log.warn( - `decryptGroupChange/${logId}: Unable to decrypt sourceUuid.`, + `decryptGroupChange/${logId}: Unable to decrypt sourceServiceId.`, Errors.toLogFormat(error) ); } - if (!isValidUuid(result.sourceUuid)) { + if (!result.sourceServiceId || !isServiceIdString(result.sourceServiceId)) { log.warn( - `decryptGroupChange/${logId}: Invalid sourceUuid. Clearing sourceUuid.` + `decryptGroupChange/${logId}: Invalid sourceServiceId. Clearing sourceServiceId.` ); - result.sourceUuid = undefined; + result.sourceServiceId = undefined; } } else { - throw new Error('decryptGroupChange: Missing sourceUuid'); + throw new Error('decryptGroupChange: Missing sourceServiceId'); } // addMembers?: Array; @@ -5888,12 +5944,9 @@ function decryptGroupChange( 'decryptGroupChange: deleteMember.deletedUserId was missing' ); - let userId: string; + let userId: AciString; try { - userId = normalizeUuid( - decryptUuid(clientZkGroupCipher, deletedUserId), - 'actions.deleteMembers.deletedUserId' - ); + userId = decryptAci(clientZkGroupCipher, deletedUserId); } catch (error) { log.warn( `decryptGroupChange/${logId}: Unable to decrypt deleteMembers.deletedUserId. Dropping member.`, @@ -5902,14 +5955,6 @@ function decryptGroupChange( return null; } - if (!isValidUuid(userId)) { - log.warn( - `decryptGroupChange/${logId}: Dropping deleteMember due to invalid userId` - ); - - return null; - } - return { deletedUserId: userId }; }) ); @@ -5922,12 +5967,9 @@ function decryptGroupChange( 'decryptGroupChange: modifyMemberRole.userId was missing' ); - let userId: string; + let userId: AciString; try { - userId = normalizeUuid( - decryptUuid(clientZkGroupCipher, modifyMember.userId), - 'actions.modifyMemberRoles.userId' - ); + userId = decryptAci(clientZkGroupCipher, modifyMember.userId); } catch (error) { log.warn( `decryptGroupChange/${logId}: Unable to decrypt modifyMemberRole.userId. Dropping member.`, @@ -5936,14 +5978,6 @@ function decryptGroupChange( return null; } - if (!isValidUuid(userId)) { - log.warn( - `decryptGroupChange/${logId}: Dropping modifyMemberRole due to invalid userId` - ); - - return null; - } - const role = dropNull(modifyMember.role); if (!isValidRole(role)) { throw new Error( @@ -5989,18 +6023,15 @@ function decryptGroupChange( 'decryptGroupChange: modifyMemberProfileKeys.profileKey was missing' ); - let uuid: UUIDStringType; + let aci: AciString; let profileKey: Uint8Array; try { - uuid = normalizeUuid( - decryptUuid(clientZkGroupCipher, userId), - 'actions.modifyMemberProfileKeys.userId' - ); + aci = decryptAci(clientZkGroupCipher, userId); profileKey = decryptProfileKey( clientZkGroupCipher, encryptedProfileKey, - uuid + aci ); } catch (error) { log.warn( @@ -6017,7 +6048,7 @@ function decryptGroupChange( ); } - return { uuid, profileKey }; + return { aci, profileKey }; }) ); @@ -6055,12 +6086,9 @@ function decryptGroupChange( Bytes.isNotEmpty(deletedUserId), 'decryptGroupChange: deletePendingMembers.deletedUserId was missing' ); - let userId: string; + let userId: ServiceIdString; try { - userId = normalizeUuid( - decryptUuid(clientZkGroupCipher, deletedUserId), - 'actions.deletePendingMembers.deletedUserId' - ); + userId = decryptServiceId(clientZkGroupCipher, deletedUserId); } catch (error) { log.warn( `decryptGroupChange/${logId}: Unable to decrypt deletePendingMembers.deletedUserId. Dropping member.`, @@ -6069,7 +6097,7 @@ function decryptGroupChange( return null; } - if (!isValidUuid(userId)) { + if (!isServiceIdString(userId)) { log.warn( `decryptGroupChange/${logId}: Dropping deletePendingMember due to invalid deletedUserId` ); @@ -6114,18 +6142,15 @@ function decryptGroupChange( 'decryptGroupChange: promotePendingMembers.profileKey was missing' ); - let uuid: UUIDStringType; + let aci: AciString; let profileKey: Uint8Array; try { - uuid = normalizeUuid( - decryptUuid(clientZkGroupCipher, userId), - 'actions.promotePendingMembers.userId' - ); + aci = decryptAci(clientZkGroupCipher, userId); profileKey = decryptProfileKey( clientZkGroupCipher, encryptedProfileKey, - uuid + aci ); } catch (error) { log.warn( @@ -6142,7 +6167,7 @@ function decryptGroupChange( ); } - return { uuid, profileKey }; + return { aci, profileKey }; }) ); @@ -6168,23 +6193,17 @@ function decryptGroupChange( 'promoteMembersPendingPniAciProfileKey.profileKey was missing' ); - let userId: string; - let pni: string; + let aci: AciString; + let pni: PniString; let profileKey: Uint8Array; try { - userId = normalizeUuid( - decryptUuid(clientZkGroupCipher, promotePendingMember.userId), - 'actions.promoteMembersPendingPniAciProfileKey.userId' - ); - pni = normalizeUuid( - decryptUuid(clientZkGroupCipher, promotePendingMember.pni), - 'actions.promoteMembersPendingPniAciProfileKey.pni' - ); + aci = decryptAci(clientZkGroupCipher, promotePendingMember.userId); + pni = decryptPni(clientZkGroupCipher, promotePendingMember.pni); profileKey = decryptProfileKey( clientZkGroupCipher, promotePendingMember.profileKey, - UUID.cast(userId) + aci ); } catch (error) { log.warn( @@ -6194,24 +6213,6 @@ function decryptGroupChange( return null; } - if (!isValidUuid(userId)) { - log.warn( - `decryptGroupChange/${logId}: Dropping ` + - 'promoteMembersPendingPniAciProfileKey due to invalid ACI' - ); - - return null; - } - - if (!isValidUuid(pni)) { - log.warn( - `decryptGroupChange/${logId}: Dropping ` + - 'promoteMembersPendingPniAciProfileKey due to invalid PNI' - ); - - return null; - } - if (!isValidProfileKey(profileKey)) { throw new Error( 'decryptGroupChange: promoteMembersPendingPniAciProfileKey ' + @@ -6220,7 +6221,7 @@ function decryptGroupChange( } return { - aci: userId, + aci, pni, profileKey, }; @@ -6363,12 +6364,9 @@ function decryptGroupChange( 'decryptGroupChange: deletePendingApproval.deletedUserId was missing' ); - let userId: string; + let aci: AciString; try { - userId = normalizeUuid( - decryptUuid(clientZkGroupCipher, deletedUserId), - 'actions.deleteMemberPendingAdminApprovals' - ); + aci = decryptAci(clientZkGroupCipher, deletedUserId); } catch (error) { log.warn( `decryptGroupChange/${logId}: Unable to decrypt deletePendingApproval.deletedUserId. Dropping member.`, @@ -6376,15 +6374,8 @@ function decryptGroupChange( ); return null; } - if (!isValidUuid(userId)) { - log.warn( - `decryptGroupChange/${logId}: Dropping deletePendingApproval due to invalid deletedUserId` - ); - return null; - } - - return { deletedUserId: userId }; + return { deletedUserId: aci }; } ) ); @@ -6401,12 +6392,9 @@ function decryptGroupChange( 'decryptGroupChange: promoteAdminApproval.userId was missing' ); - let decryptedUserId: string; + let decryptedUserId: AciString; try { - decryptedUserId = normalizeUuid( - decryptUuid(clientZkGroupCipher, userId), - 'actions.promoteMemberPendingAdminApprovals.userId' - ); + decryptedUserId = decryptAci(clientZkGroupCipher, userId); } catch (error) { log.warn( `decryptGroupChange/${logId}: Unable to decrypt promoteAdminApproval.userId. Dropping member.`, @@ -6478,13 +6466,13 @@ function decryptGroupChange( ); return null; } - const uuid = normalizeUuid( - decryptUuid(clientZkGroupCipher, item.added.userId), - 'addMembersBanned.added.userId' + const serviceId = decryptServiceId( + clientZkGroupCipher, + item.added.userId ); const timestamp = normalizeTimestamp(item.added.timestamp); - return { uuid, timestamp }; + return { serviceId, timestamp }; }) .filter(isNotNil); } @@ -6499,10 +6487,7 @@ function decryptGroupChange( ); return null; } - return normalizeUuid( - decryptUuid(clientZkGroupCipher, item.deletedUserId), - 'deleteMembersBanned.deletedUserId' - ); + return decryptServiceId(clientZkGroupCipher, item.deletedUserId); }) .filter(isNotNil); } @@ -6618,9 +6603,13 @@ function decryptGroupState( const { accessControl } = groupState; strictAssert(accessControl, 'No accessControl field found'); - const attributes = dropNull(accessControl.attributes); - const members = dropNull(accessControl.members); - const addFromInviteLink = dropNull(accessControl.addFromInviteLink); + const attributes = + accessControl.attributes ?? Proto.AccessControl.AccessRequired.UNKNOWN; + const members = + accessControl.members ?? Proto.AccessControl.AccessRequired.UNKNOWN; + const addFromInviteLink = + accessControl.addFromInviteLink ?? + Proto.AccessControl.AccessRequired.UNKNOWN; strictAssert( isValidAccess(attributes), @@ -6643,11 +6632,12 @@ function decryptGroupState( } // version + const version = groupState.version ?? 0; strictAssert( - isNumber(groupState.version), - `decryptGroupState: Expected version to be a number; it was ${groupState.version}` + isNumber(version), + `decryptGroupState: Expected version to be a number or null; it was ${groupState.version}` ); - result.version = groupState.version; + result.version = version; // members if (groupState.members) { @@ -6712,13 +6702,10 @@ function decryptGroupState( ); return null; } - const uuid = normalizeUuid( - decryptUuid(clientZkGroupCipher, item.userId), - 'membersBanned.added.userId' - ); + const serviceId = decryptServiceId(clientZkGroupCipher, item.userId); const timestamp = item.timestamp?.toNumber() ?? 0; - return { uuid, timestamp }; + return { serviceId, timestamp }; }) .filter(isNotNil); } else { @@ -6731,10 +6718,10 @@ function decryptGroupState( } type DecryptedMember = Readonly<{ - userId: string; + userId: AciString; profileKey: Uint8Array; role: Proto.Member.Role; - joinedAtVersion?: number; + joinedAtVersion: number; }>; function decryptMember( @@ -6748,12 +6735,9 @@ function decryptMember( 'decryptMember: Member had missing userId' ); - let userId: string; + let userId: AciString; try { - userId = normalizeUuid( - decryptUuid(clientZkGroupCipher, member.userId), - 'decryptMember.userId' - ); + userId = decryptAci(clientZkGroupCipher, member.userId); } catch (error) { log.warn( `decryptMember/${logId}: Unable to decrypt member userid. Dropping member.`, @@ -6762,12 +6746,6 @@ function decryptMember( return undefined; } - if (!isValidUuid(userId)) { - log.warn(`decryptMember/${logId}: Dropping member due to invalid userId`); - - return undefined; - } - // profileKey strictAssert( Bytes.isNotEmpty(member.profileKey), @@ -6776,7 +6754,7 @@ function decryptMember( const profileKey = decryptProfileKey( clientZkGroupCipher, member.profileKey, - UUID.cast(userId) + userId ); if (!isValidProfileKey(profileKey)) { @@ -6794,15 +6772,15 @@ function decryptMember( userId, profileKey, role, - joinedAtVersion: dropNull(member.joinedAtVersion), + joinedAtVersion: dropNull(member.joinedAtVersion) ?? 0, }; } type DecryptedMemberPendingProfileKey = { - addedByUserId: string; + addedByUserId: AciString; timestamp: number; member: { - userId: string; + userId: ServiceIdString; role?: Proto.Member.Role; }; }; @@ -6818,12 +6796,9 @@ function decryptMemberPendingProfileKey( 'decryptMemberPendingProfileKey: Member had missing addedByUserId' ); - let addedByUserId: string; + let addedByUserId: AciString; try { - addedByUserId = normalizeUuid( - decryptUuid(clientZkGroupCipher, member.addedByUserId), - 'decryptMemberPendingProfileKey.addedByUserId' - ); + addedByUserId = decryptAci(clientZkGroupCipher, member.addedByUserId); } catch (error) { log.warn( `decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member addedByUserId. Dropping member.`, @@ -6832,13 +6807,6 @@ function decryptMemberPendingProfileKey( return undefined; } - if (!isValidUuid(addedByUserId)) { - log.warn( - `decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid addedByUserId` - ); - return undefined; - } - // timestamp const timestamp = normalizeTimestamp(member.timestamp); @@ -6862,12 +6830,9 @@ function decryptMemberPendingProfileKey( 'decryptMemberPendingProfileKey: Member had missing member.userId' ); - let decryptedUserId: string; + let decryptedUserId: ServiceIdString; try { - decryptedUserId = normalizeUuid( - decryptUuid(clientZkGroupCipher, userId), - 'decryptMemberPendingProfileKey.member.userId' - ); + decryptedUserId = decryptServiceId(clientZkGroupCipher, userId); } catch (error) { log.warn( `decryptMemberPendingProfileKey/${logId}: Unable to decrypt pending member userId. Dropping member.`, @@ -6876,14 +6841,6 @@ function decryptMemberPendingProfileKey( return undefined; } - if (!isValidUuid(decryptedUserId)) { - log.warn( - `decryptMemberPendingProfileKey/${logId}: Dropping pending member due to invalid member.userId` - ); - - return undefined; - } - // role const role = dropNull(member.member.role); @@ -6903,7 +6860,7 @@ function decryptMemberPendingProfileKey( } type DecryptedMemberPendingAdminApproval = { - userId: string; + userId: AciString; profileKey?: Uint8Array; timestamp: number; }; @@ -6924,12 +6881,9 @@ function decryptMemberPendingAdminApproval( 'decryptMemberPendingAdminApproval: Missing userId' ); - let decryptedUserId: string; + let decryptedUserId: AciString; try { - decryptedUserId = normalizeUuid( - decryptUuid(clientZkGroupCipher, userId), - 'decryptMemberPendingAdminApproval.userId' - ); + decryptedUserId = decryptAci(clientZkGroupCipher, userId); } catch (error) { log.warn( `decryptMemberPendingAdminApproval/${logId}: Unable to decrypt pending member userId. Dropping member.`, @@ -6938,14 +6892,6 @@ function decryptMemberPendingAdminApproval( return undefined; } - if (!isValidUuid(decryptedUserId)) { - log.warn( - `decryptMemberPendingAdminApproval/${logId}: Invalid userId. Dropping member.` - ); - - return undefined; - } - // profileKey let decryptedProfileKey: Uint8Array | undefined; if (Bytes.isNotEmpty(profileKey)) { @@ -6953,7 +6899,7 @@ function decryptMemberPendingAdminApproval( decryptedProfileKey = decryptProfileKey( clientZkGroupCipher, profileKey, - UUID.cast(decryptedUserId) + decryptedUserId ); } catch (error) { log.warn( @@ -6980,7 +6926,7 @@ function decryptMemberPendingAdminApproval( export function getMembershipList( conversationId: string -): Array<{ uuid: UUIDStringType; uuidCiphertext: Uint8Array }> { +): Array<{ aci: AciString; uuidCiphertext: Uint8Array }> { const conversation = window.ConversationController.get(conversationId); if (!conversation) { throw new Error('getMembershipList: cannot find conversation'); @@ -6994,9 +6940,9 @@ export function getMembershipList( const clientZkGroupCipher = getClientZkGroupCipher(secretParams); return conversation.getMembers().map(member => { - const uuid = member.getCheckedUuid('getMembershipList: member has no UUID'); + const aci = member.getCheckedAci('getMembershipList: member has no aci'); - const uuidCiphertext = encryptUuid(clientZkGroupCipher, uuid); - return { uuid: uuid.toString(), uuidCiphertext }; + const uuidCiphertext = encryptServiceId(clientZkGroupCipher, aci); + return { aci, uuidCiphertext }; }); } diff --git a/ts/groups/joinViaLink.ts b/ts/groups/joinViaLink.ts index 2008e2447b..88cfc5200a 100644 --- a/ts/groups/joinViaLink.ts +++ b/ts/groups/joinViaLink.ts @@ -13,7 +13,6 @@ import * as log from '../logging/log'; import { HTTPError } from '../textsecure/Errors'; import { SignalService as Proto } from '../protobuf'; import { ToastType } from '../types/Toast'; -import { UUIDKind } from '../types/UUID'; import { applyNewAvatar, decryptGroupDescription, @@ -30,12 +29,13 @@ import { isAccessControlEnabled } from './util'; import { isGroupV1 } from '../util/whatTypeOfConversation'; import { longRunningTaskWrapper } from '../util/longRunningTaskWrapper'; import { sleep } from '../util/sleep'; +import { dropNull } from '../util/dropNull'; -export async function joinViaLink(hash: string): Promise { +export async function joinViaLink(value: string): Promise { let inviteLinkPassword: string; let masterKey: string; try { - ({ inviteLinkPassword, masterKey } = parseGroupLink(hash)); + ({ inviteLinkPassword, masterKey } = parseGroupLink(value)); } catch (error: unknown) { const errorString = Errors.toLogFormat(error); log.error(`joinViaLink: Failed to parse group link ${errorString}`); @@ -63,9 +63,9 @@ export async function joinViaLink(hash: string): Promise { const existingConversation = window.ConversationController.get(id) || window.ConversationController.getByDerivedGroupV2Id(id); - const ourUuid = window.textsecure.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.textsecure.storage.user.getCheckedAci(); - if (existingConversation && existingConversation.hasMember(ourUuid)) { + if (existingConversation && existingConversation.hasMember(ourAci)) { log.warn( `joinViaLink/${logId}: Already a member of group, opening conversation` ); @@ -117,7 +117,7 @@ export async function joinViaLink(hash: string): Promise { return; } - if (!isAccessControlEnabled(result.addFromInviteLink)) { + if (!isAccessControlEnabled(dropNull(result.addFromInviteLink))) { log.error( `joinViaLink/${logId}: addFromInviteLink value of ${result.addFromInviteLink} is invalid` ); @@ -139,17 +139,17 @@ export async function joinViaLink(hash: string): Promise { result.addFromInviteLink === Proto.AccessControl.AccessRequired.ADMINISTRATOR; const title = - decryptGroupTitle(result.title, secretParams) || + decryptGroupTitle(dropNull(result.title), secretParams) || window.i18n('icu:unknownGroup'); const groupDescription = decryptGroupDescription( - result.descriptionBytes, + dropNull(result.descriptionBytes), secretParams ); if ( approvalRequired && existingConversation && - existingConversation.isMemberAwaitingApproval(ourUuid) + existingConversation.isMemberAwaitingApproval(ourAci) ) { log.warn( `joinViaLink/${logId}: Already awaiting approval, opening conversation` @@ -246,9 +246,9 @@ export async function joinViaLink(hash: string): Promise { // via some other process. If so, just open that conversation. if ( targetConversation && - (targetConversation.hasMember(ourUuid) || + (targetConversation.hasMember(ourAci) || (approvalRequired && - targetConversation.isMemberAwaitingApproval(ourUuid))) + targetConversation.isMemberAwaitingApproval(ourAci))) ) { log.warn( `joinViaLink/${logId}: User is part of group on second check, opening conversation` @@ -317,7 +317,7 @@ export async function joinViaLink(hash: string): Promise { groupInviteLinkPassword: inviteLinkPassword, left: true, name: title, - revision: result.version, + revision: dropNull(result.version), temporaryMemberCount: memberCount, timestamp, }); diff --git a/ts/hooks/useActivateSpeakerViewOnPresenting.ts b/ts/hooks/useActivateSpeakerViewOnPresenting.ts index d3781e0226..5ba8ffff1c 100644 --- a/ts/hooks/useActivateSpeakerViewOnPresenting.ts +++ b/ts/hooks/useActivateSpeakerViewOnPresenting.ts @@ -1,16 +1,26 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import { useEffect } from 'react'; +import { useEffect, useMemo } from 'react'; +import type { AciString } from '../types/ServiceId'; import { usePrevious } from './usePrevious'; type RemoteParticipant = { hasRemoteVideo: boolean; presenting: boolean; title: string; - uuid?: string; + aci?: AciString; }; +export function usePresenter( + remoteParticipants: ReadonlyArray +): AciString | undefined { + return useMemo( + () => remoteParticipants.find(participant => participant.presenting)?.aci, + [remoteParticipants] + ); +} + export function useActivateSpeakerViewOnPresenting({ remoteParticipants, switchToPresentationView, @@ -20,20 +30,18 @@ export function useActivateSpeakerViewOnPresenting({ switchToPresentationView: () => void; switchFromPresentationView: () => void; }): void { - const presenterUuid = remoteParticipants.find( - participant => participant.presenting - )?.uuid; - const prevPresenterUuid = usePrevious(presenterUuid, presenterUuid); + const presenterAci = usePresenter(remoteParticipants); + const prevPresenterAci = usePrevious(presenterAci, presenterAci); useEffect(() => { - if (prevPresenterUuid !== presenterUuid && presenterUuid) { + if (prevPresenterAci !== presenterAci && presenterAci) { switchToPresentationView(); - } else if (prevPresenterUuid && !presenterUuid) { + } else if (prevPresenterAci && !presenterAci) { switchFromPresentationView(); } }, [ - presenterUuid, - prevPresenterUuid, + presenterAci, + prevPresenterAci, switchToPresentationView, switchFromPresentationView, ]); diff --git a/ts/hooks/useIsMounted.ts b/ts/hooks/useIsMounted.ts new file mode 100644 index 0000000000..cdebec5f53 --- /dev/null +++ b/ts/hooks/useIsMounted.ts @@ -0,0 +1,28 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { useCallback, useEffect, useRef } from 'react'; + +/** + * If you get a warning like: + * + * Warning: Can't perform a React state update on an unmounted component. + * + * your component is probably trying to set state after it has unmounted, e.g. after a + * timeout or async call. If you can, clear the timeout when the component unmounts (e.g. + * on useEffect cleanup). Otherwise, use this hook to check if the component is mounted + * before updating state. + */ + +export function useIsMounted(): () => boolean { + const isMounted = useRef(false); + + useEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, []); + + return useCallback(() => isMounted.current === true, []); +} diff --git a/ts/hooks/useKeyboardShortcuts.tsx b/ts/hooks/useKeyboardShortcuts.tsx index 552c8a01a9..24e57c07b6 100644 --- a/ts/hooks/useKeyboardShortcuts.tsx +++ b/ts/hooks/useKeyboardShortcuts.tsx @@ -10,7 +10,6 @@ import * as KeyboardLayout from '../services/keyboardLayout'; import { getHasPanelOpen } from '../state/selectors/conversations'; import { isInFullScreenCall } from '../state/selectors/calling'; import { isShowingAnyModal } from '../state/selectors/globalModals'; -import { shouldShowStoriesView } from '../state/selectors/stories'; type KeyboardShortcutHandlerType = (ev: KeyboardEvent) => boolean; @@ -36,10 +35,6 @@ function useHasGlobalModal(): boolean { return useSelector(isShowingAnyModal); } -function useHasStories(): boolean { - return useSelector(shouldShowStoriesView); -} - function useHasCalling(): boolean { return useSelector(isInFullScreenCall); } @@ -47,10 +42,9 @@ function useHasCalling(): boolean { function useHasAnyOverlay(): boolean { const panels = useHasPanels(); const globalModal = useHasGlobalModal(); - const stories = useHasStories(); const calling = useHasCalling(); - return panels || globalModal || stories || calling; + return panels || globalModal || calling; } export function useActiveCallShortcuts( @@ -276,6 +270,11 @@ export function useEditLastMessageSent( const key = KeyboardLayout.lookup(ev); + const { shiftKey } = ev; + if (shiftKey || isCtrlOrAlt(ev)) { + return false; + } + if (key === 'ArrowUp') { const value = maybeEditMessage(); if (value) { diff --git a/ts/hooks/useScrollLock.tsx b/ts/hooks/useScrollLock.tsx new file mode 100644 index 0000000000..53da7813b7 --- /dev/null +++ b/ts/hooks/useScrollLock.tsx @@ -0,0 +1,87 @@ +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { useContext, createContext, useEffect, useRef } from 'react'; +import * as log from '../logging/log'; + +export type ScrollerLock = Readonly<{ + isLocked(): boolean; + lock(reason: string, onUserInterrupt: () => void): () => void; + onUserInterrupt(reason: string): void; +}>; + +export function createScrollerLock( + title: string, + onUpdate: () => void +): ScrollerLock { + const locks = new Set<() => void>(); + + let lastUpdate: boolean | null = null; + function update() { + const isLocked = locks.size > 0; + if (isLocked !== lastUpdate) { + lastUpdate = isLocked; + onUpdate(); + } + } + + return { + isLocked() { + return locks.size > 0; + }, + lock(reason, onUserInterrupt) { + log.info('ScrollerLock: Locking', title, reason); + locks.add(onUserInterrupt); + update(); + function release() { + log.info('ScrollerLock: Releasing', title, reason); + locks.delete(onUserInterrupt); + update(); + } + return release; + }, + onUserInterrupt(reason) { + // Ignore interuptions if we're not locked + if (locks.size > 0) { + log.info('ScrollerLock: User Interrupt', title, reason); + locks.forEach(listener => listener()); + locks.clear(); + update(); + } + }, + }; +} + +export const ScrollerLockContext = createContext(null); + +export type ScrollLockProps = Readonly<{ + reason: string; + lockScrollWhen: boolean; + onUserInterrupt(): void; +}>; + +export function useScrollerLock({ + reason, + lockScrollWhen, + onUserInterrupt, +}: ScrollLockProps): void { + const scrollerLock = useContext(ScrollerLockContext); + + if (scrollerLock == null) { + throw new Error('Missing '); + } + + const onUserInterruptRef = useRef(onUserInterrupt); + useEffect(() => { + onUserInterruptRef.current = onUserInterrupt; + }, [onUserInterrupt]); + + useEffect(() => { + if (lockScrollWhen) { + return scrollerLock.lock(reason, () => { + onUserInterruptRef.current(); + }); + } + return undefined; + }, [reason, scrollerLock, lockScrollWhen, onUserInterrupt]); +} diff --git a/ts/hooks/useSizeObserver.tsx b/ts/hooks/useSizeObserver.tsx index 024730d93f..ccee503ff7 100644 --- a/ts/hooks/useSizeObserver.tsx +++ b/ts/hooks/useSizeObserver.tsx @@ -93,11 +93,10 @@ export function SizeObserver({ return children(ref, size); } -export type Scroll = Readonly<{ - scrollTop: number; - scrollHeight: number; - clientHeight: number; -}>; +// Note: You should just be able to pass an element into utils if you want. +export type Scroll = Readonly< + Pick +>; export type ScrollChangeHandler = (scroll: Scroll) => void; diff --git a/ts/jobs/JobQueue.ts b/ts/jobs/JobQueue.ts index 8cd58fdd9b..09d1454564 100644 --- a/ts/jobs/JobQueue.ts +++ b/ts/jobs/JobQueue.ts @@ -13,6 +13,7 @@ import * as log from '../logging/log'; import { JobLogger } from './JobLogger'; import * as Errors from '../types/errors'; import type { LoggerType } from '../types/Logging'; +import { drop } from '../util/drop'; const noopOnCompleteCallbacks = { resolve: noop, @@ -43,6 +44,12 @@ type JobQueueOptions = { logger?: LoggerType; }; +export enum JOB_STATUS { + SUCCESS = 'SUCCESS', + NEEDS_RETRY = 'NEEDS_RETRY', + ERROR = 'ERROR', +} + export abstract class JobQueue { private readonly maxAttempts: number; @@ -119,7 +126,7 @@ export abstract class JobQueue { protected abstract run( job: Readonly>, extra?: Readonly<{ attempt?: number; log?: LoggerType }> - ): Promise; + ): Promise; protected getQueues(): ReadonlySet { return new Set([this.defaultInMemoryQueue]); @@ -144,7 +151,7 @@ export abstract class JobQueue { log.info(`${this.logPrefix} is shutting down. Can't accept more work.`); break; } - void this.enqueueStoredJob(storedJob); + drop(this.enqueueStoredJob(storedJob)); } } @@ -201,7 +208,9 @@ export abstract class JobQueue { return this.defaultInMemoryQueue; } - private async enqueueStoredJob(storedJob: Readonly) { + protected async enqueueStoredJob( + storedJob: Readonly + ): Promise { assertDev( storedJob.queueType === this.queueType, 'Received a mis-matched queue type' @@ -242,50 +251,78 @@ export abstract class JobQueue { const result: | undefined - | { success: true } - | { success: false; err: unknown } = await queue.add(async () => { - for (let attempt = 1; attempt <= this.maxAttempts; attempt += 1) { - const isFinalAttempt = attempt === this.maxAttempts; + | { status: JOB_STATUS.SUCCESS } + | { status: JOB_STATUS.NEEDS_RETRY } + | { status: JOB_STATUS.ERROR; err: unknown } = await queue.add( + async () => { + for (let attempt = 1; attempt <= this.maxAttempts; attempt += 1) { + const isFinalAttempt = attempt === this.maxAttempts; - logger.attempt = attempt; + logger.attempt = attempt; - log.info( - `${this.logPrefix} running job ${storedJob.id}, attempt ${attempt} of ${this.maxAttempts}` - ); - - if (this.isShuttingDown) { - log.warn( - `${this.logPrefix} returning early for job ${storedJob.id}; shutting down` - ); - return { success: false, err: new Error('Shutting down') }; - } - - try { - // We want an `await` in the loop, as we don't want a single job running more - // than once at a time. Ideally, the job will succeed on the first attempt. - // eslint-disable-next-line no-await-in-loop - await this.run(parsedJob, { attempt, log: logger }); log.info( - `${this.logPrefix} job ${storedJob.id} succeeded on attempt ${attempt}` + `${this.logPrefix} running job ${storedJob.id}, attempt ${attempt} of ${this.maxAttempts}` ); - return { success: true }; - } catch (err: unknown) { - log.error( - `${this.logPrefix} job ${ - storedJob.id - } failed on attempt ${attempt}. ${Errors.toLogFormat(err)}` - ); - if (isFinalAttempt) { - return { success: false, err }; + + if (this.isShuttingDown) { + log.warn( + `${this.logPrefix} returning early for job ${storedJob.id}; shutting down` + ); + return { + status: JOB_STATUS.ERROR, + err: new Error('Shutting down'), + }; + } + + try { + // We want an `await` in the loop, as we don't want a single job running more + // than once at a time. Ideally, the job will succeed on the first attempt. + // eslint-disable-next-line no-await-in-loop + const jobStatus = await this.run(parsedJob, { + attempt, + log: logger, + }); + if (!jobStatus) { + log.info( + `${this.logPrefix} job ${storedJob.id} succeeded on attempt ${attempt}` + ); + return { status: JOB_STATUS.SUCCESS }; + } + log.info( + `${this.logPrefix} job ${storedJob.id} returned status ${jobStatus} on attempt ${attempt}` + ); + return { status: jobStatus }; + } catch (err: unknown) { + log.error( + `${this.logPrefix} job ${ + storedJob.id + } failed on attempt ${attempt}. ${Errors.toLogFormat(err)}` + ); + if (isFinalAttempt) { + return { status: JOB_STATUS.ERROR, err }; + } } } + + // This should never happen. See the assertion below. + return undefined; } + ); - // This should never happen. See the assertion below. - return undefined; - }); - - if (result?.success || !this.isShuttingDown) { + if (result?.status === JOB_STATUS.NEEDS_RETRY) { + const addJobSuccess = await this.retryJobOnQueueIdle({ + storedJob, + job: parsedJob, + logger, + }); + if (!addJobSuccess) { + await this.store.delete(storedJob.id); + } + } + if ( + result?.status === JOB_STATUS.SUCCESS || + (result?.status === JOB_STATUS.ERROR && !this.isShuttingDown) + ) { await this.store.delete(storedJob.id); } @@ -293,13 +330,26 @@ export abstract class JobQueue { result, 'The job never ran. This indicates a developer error in the job queue' ); - if (result.success) { - resolve(); - } else { + if (result.status === JOB_STATUS.ERROR) { reject(result.err); + } else { + resolve(); } } + async retryJobOnQueueIdle({ + logger, + }: { + job: Readonly>; + storedJob: Readonly; + logger: LoggerType; + }): Promise { + logger.error( + `retryJobOnQueueIdle: not implemented for queue ${this.queueType}; dropping job` + ); + return false; + } + async shutdown(): Promise { const queues = this.getQueues(); log.info( diff --git a/ts/jobs/conversationJobQueue.ts b/ts/jobs/conversationJobQueue.ts index 46351e8ce7..1c95cabd68 100644 --- a/ts/jobs/conversationJobQueue.ts +++ b/ts/jobs/conversationJobQueue.ts @@ -9,7 +9,7 @@ import * as durations from '../util/durations'; import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff'; import { InMemoryQueues } from './helpers/InMemoryQueues'; import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; -import { JobQueue } from './JobQueue'; +import { JOB_STATUS, JobQueue } from './JobQueue'; import { sendNormalMessage } from './helpers/sendNormalMessage'; import { sendDirectExpirationTimerUpdate } from './helpers/sendDirectExpirationTimerUpdate'; @@ -33,16 +33,20 @@ import { strictAssert } from '../util/assert'; import { missingCaseError } from '../util/missingCaseError'; import { explodePromise } from '../util/explodePromise'; import type { Job } from './Job'; -import type { ParsedJob } from './types'; +import type { ParsedJob, StoredJob } from './types'; import type SendMessage from '../textsecure/SendMessage'; -import type { UUIDStringType } from '../types/UUID'; +import type { ServiceIdString } from '../types/ServiceId'; import { commonShouldJobContinue } from './helpers/commonShouldJobContinue'; import { sleeper } from '../util/sleeper'; import { receiptSchema, ReceiptType } from '../types/Receipt'; +import { serviceIdSchema, aciSchema } from '../types/ServiceId'; import { sendResendRequest } from './helpers/sendResendRequest'; import { sendNullMessage } from './helpers/sendNullMessage'; import { sendSenderKeyDistribution } from './helpers/sendSenderKeyDistribution'; import { sendSavedProto } from './helpers/sendSavedProto'; +import { drop } from '../util/drop'; +import { isInPast } from '../util/timestamp'; +import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary'; // Note: generally, we only want to add to this list. If you do need to change one of // these values, you'll likely need to write a database migration. @@ -61,6 +65,7 @@ export const conversationQueueJobEnum = z.enum([ 'Story', 'Receipts', ]); +type ConversationQueueJobEnum = z.infer; const deleteForEveryoneJobDataSchema = z.object({ type: z.literal(conversationQueueJobEnum.enum.DeleteForEveryone), @@ -82,12 +87,7 @@ const deleteStoryForEveryoneJobDataSchema = z.object({ updatedStoryRecipients: z .array( z.object({ - // TODO: DESKTOP-5630 - destinationUuid: z.string().optional(), - legacyDestinationUuid: z.string().optional(), - - destinationAci: z.string().optional(), - destinationPni: z.string().optional(), + destinationServiceId: serviceIdSchema.optional(), distributionListIds: z.array(z.string()), isAllowedToReply: z.boolean(), }) @@ -162,7 +162,7 @@ const resendRequestJobDataSchema = z.object({ plaintext: z.string(), receivedAtCounter: z.number(), receivedAtDate: z.number(), - senderUuid: z.string(), + senderAci: aciSchema, senderDevice: z.number(), timestamp: z.number(), }); @@ -238,7 +238,92 @@ export type ConversationQueueJobBundle = { const MAX_RETRY_TIME = durations.DAY; const MAX_ATTEMPTS = exponentialBackoffMaxAttempts(MAX_RETRY_TIME); +function shouldSendShowCaptcha(type: ConversationQueueJobEnum): boolean { + if (type === 'DeleteForEveryone') { + return true; + } + if (type === 'DeleteStoryForEveryone') { + return true; + } + if (type === 'DirectExpirationTimerUpdate') { + return true; + } + if (type === 'GroupUpdate') { + return false; + } + if (type === 'NormalMessage') { + return true; + } + if (type === 'NullMessage') { + return false; + } + if (type === 'ProfileKey') { + return false; + } + if (type === 'Reaction') { + return false; + } + if (type === 'ResendRequest') { + return false; + } + if (type === 'SavedProto') { + return false; + } + if (type === 'SenderKeyDistribution') { + return false; + } + if (type === 'Story') { + return true; + } + if (type === 'Receipts') { + return false; + } + + throw missingCaseError(type); +} + +enum RETRY_STATUS { + BLOCKED = 'BLOCKED', + BLOCKED_WITH_JOBS = 'BLOCKED_WITH_JOBS', + UNBLOCKED = 'UNBLOCKED', +} + +type ConversationData = Readonly< + | { + // When we get a retryAt from a 428 error, we immediately record it, but we don't + // yet have a job to retry. We should, very soon, when the job returns + // JOB_STATUS.NEEDS_RETRY. This should be a very short-lived state. + status: RETRY_STATUS.BLOCKED; + callback: undefined; + jobsNeedingRetry: undefined; + retryAt: number; + } + | { + // This is the next stage, when we've added at least one job needing retry, and we + // have a callback registered to run on queue idle (or be called directly). + status: RETRY_STATUS.BLOCKED_WITH_JOBS; + callback: () => void; + jobsNeedingRetry: Array>; + retryAt: number; + retryAtTimeout?: NodeJS.Timeout; + } + | { + // When we discover that we can now run these deferred jobs, we flip into this + // state, which should be short-lived. We very quickly re-enqueue all + // jobsNeedingRetry, and erase perConversationData for this conversation. + status: RETRY_STATUS.UNBLOCKED; + callback: () => void; + jobsNeedingRetry: Array>; + retryAt: undefined; + retryAtTimeout?: NodeJS.Timeout; + } +>; + export class ConversationJobQueue extends JobQueue { + private readonly perConversationData = new Map< + string, + ConversationData | undefined + >(); private readonly inMemoryQueues = new InMemoryQueues(); private readonly verificationWaitMap = new Map< string, @@ -248,6 +333,7 @@ export class ConversationJobQueue extends JobQueue { promise: Promise; } >(); + private callbackCount = 0; override getQueues(): ReadonlySet { return this.inMemoryQueues.allQueues; @@ -258,14 +344,17 @@ export class ConversationJobQueue extends JobQueue { insert?: (job: ParsedJob) => Promise ): Promise> { const { conversationId, type } = data; - strictAssert( - window.Signal.challengeHandler, - 'conversationJobQueue.add: Missing challengeHandler!' - ); - window.Signal.challengeHandler.maybeSolve({ - conversationId, - reason: `conversationJobQueue.add(${conversationId}, ${type})`, - }); + + if (shouldSendShowCaptcha(data.type)) { + strictAssert( + window.Signal.challengeHandler, + 'conversationJobQueue.add: Missing challengeHandler!' + ); + window.Signal.challengeHandler.maybeSolve({ + conversationId, + reason: `conversationJobQueue.add(${conversationId}, ${type})`, + }); + } return super.add(data, insert); } @@ -314,18 +403,239 @@ export class ConversationJobQueue extends JobQueue { globalLogger.warn( `resolveVerificationWaiter: Missing waiter for conversation ${conversationId}.` ); + this.unblockConversationRetries(conversationId); } } + private unblockConversationRetries(conversationId: string) { + const logId = `unblockConversationRetries/${conversationId}`; + + const perConversationData = this.perConversationData.get(conversationId); + if (!perConversationData) { + return; + } + + const { status, callback } = perConversationData; + if (status === RETRY_STATUS.BLOCKED) { + globalLogger.info( + `${logId}: Deleting previous BLOCKED state; had no jobs` + ); + this.perConversationData.delete(conversationId); + } else if (status === RETRY_STATUS.BLOCKED_WITH_JOBS) { + globalLogger.info( + `${logId}: Moving previous WAITING state to UNBLOCKED, calling callback directly` + ); + this.perConversationData.set(conversationId, { + ...perConversationData, + status: RETRY_STATUS.UNBLOCKED, + retryAt: undefined, + }); + callback(); + } else if (status === RETRY_STATUS.UNBLOCKED) { + globalLogger.warn( + `${logId}: We're still in UNBLOCKED state; calling callback directly` + ); + callback(); + } else { + throw missingCaseError(status); + } + } + + private captureRetryAt(conversationId: string, retryAt: number | undefined) { + const logId = `captureRetryAt/${conversationId}`; + + const newRetryAt = retryAt || Date.now() + MINUTE; + const perConversationData = this.perConversationData.get(conversationId); + if (!perConversationData) { + if (!retryAt) { + globalLogger.warn( + `${logId}: No existing data, using retryAt of ${newRetryAt}` + ); + } + this.perConversationData.set(conversationId, { + status: RETRY_STATUS.BLOCKED, + retryAt: newRetryAt, + callback: undefined, + jobsNeedingRetry: undefined, + }); + + return; + } + + const { status, retryAt: existingRetryAt } = perConversationData; + if (existingRetryAt && existingRetryAt >= newRetryAt) { + globalLogger.warn( + `${logId}: New newRetryAt ${newRetryAt} isn't after existing retryAt ${existingRetryAt}, dropping` + ); + return; + } + + if ( + status === RETRY_STATUS.BLOCKED || + status === RETRY_STATUS.BLOCKED_WITH_JOBS + ) { + globalLogger.info( + `${logId}: Updating to newRetryAt ${newRetryAt} from existing retryAt ${existingRetryAt}, status ${status}` + ); + this.perConversationData.set(conversationId, { + ...perConversationData, + retryAt: newRetryAt, + }); + } else if (status === RETRY_STATUS.UNBLOCKED) { + globalLogger.info( + `${logId}: Updating to newRetryAt ${newRetryAt} from previous UNBLOCKED status` + ); + this.perConversationData.set(conversationId, { + ...perConversationData, + status: RETRY_STATUS.BLOCKED_WITH_JOBS, + retryAt: newRetryAt, + }); + } else { + throw missingCaseError(status); + } + } + + override async retryJobOnQueueIdle({ + job, + storedJob, + logger, + }: { + job: Readonly>; + storedJob: Readonly; + logger: LoggerType; + }): Promise { + const { conversationId } = job.data; + const logId = `retryJobOnQueueIdle/${conversationId}/${job.id}`; + const perConversationData = this.perConversationData.get(conversationId); + + if (!perConversationData) { + logger.warn(`${logId}: no data for conversation; using default retryAt`); + } else { + logger.warn( + `${logId}: adding to existing data with status ${perConversationData.status}` + ); + } + + const { status, retryAt, jobsNeedingRetry, callback } = + perConversationData || { + status: RETRY_STATUS.BLOCKED, + retryAt: Date.now() + MINUTE, + }; + + const newJobsNeedingRetry = (jobsNeedingRetry || []).concat([storedJob]); + logger.info( + `${logId}: job added to retry queue with status ${status}; ${newJobsNeedingRetry.length} items now in queue` + ); + + const newCallback = + callback || this.createRetryCallback(conversationId, job.id); + + if ( + status === RETRY_STATUS.BLOCKED || + status === RETRY_STATUS.BLOCKED_WITH_JOBS + ) { + this.perConversationData.set(conversationId, { + status: RETRY_STATUS.BLOCKED_WITH_JOBS, + retryAt, + jobsNeedingRetry: newJobsNeedingRetry, + callback: newCallback, + }); + } else { + this.perConversationData.set(conversationId, { + status: RETRY_STATUS.UNBLOCKED, + retryAt, + jobsNeedingRetry: newJobsNeedingRetry, + callback: newCallback, + }); + } + + if (newCallback !== callback) { + const queue = this.getInMemoryQueue(job); + drop( + // eslint-disable-next-line more/no-then + queue.onIdle().then(() => { + globalLogger.info(`${logId}: Running callback due to queue.onIdle`); + newCallback(); + }) + ); + } + + return true; + } + + private createRetryCallback(conversationId: string, jobId: string) { + this.callbackCount += 1; + const id = this.callbackCount; + + globalLogger.info( + `createRetryCallback/${conversationId}/${id}: callback created for job ${jobId}` + ); + + return () => { + const logId = `retryCallback/${conversationId}/${id}`; + + const perConversationData = this.perConversationData.get(conversationId); + if (!perConversationData) { + globalLogger.warn(`${logId}: no perConversationData, returning early.`); + return; + } + + const { status, retryAt } = perConversationData; + if (status === RETRY_STATUS.BLOCKED) { + globalLogger.warn( + `${logId}: Still in blocked state, no jobs to retry. Clearing perConversationData.` + ); + this.perConversationData.delete(conversationId); + return; + } + + const { callback, jobsNeedingRetry, retryAtTimeout } = + perConversationData; + + if (retryAtTimeout) { + clearTimeoutIfNecessary(retryAtTimeout); + } + + if (!retryAt || isInPast(retryAt)) { + globalLogger.info( + `${logId}: retryAt is ${retryAt}; queueing ${jobsNeedingRetry?.length} jobs needing retry` + ); + + // We're starting to retry jobs; remove the challenge handler + drop(window.Signal.challengeHandler?.unregister(conversationId, logId)); + + jobsNeedingRetry?.forEach(job => { + drop(this.enqueueStoredJob(job)); + }); + this.perConversationData.delete(conversationId); + return; + } + + const timeLeft = retryAt - Date.now(); + globalLogger.info( + `${logId}: retryAt ${retryAt} is in the future, scheduling timeout for ${timeLeft}ms` + ); + + this.perConversationData.set(conversationId, { + ...perConversationData, + retryAtTimeout: setTimeout(() => { + globalLogger.info(`${logId}: Running callback due to timeout`); + callback(); + }, timeLeft), + }); + }; + } + protected async run( { data, timestamp, }: Readonly<{ data: ConversationQueueJobData; timestamp: number }>, { attempt, log }: Readonly<{ attempt: number; log: LoggerType }> - ): Promise { + ): Promise { const { type, conversationId } = data; const isFinalAttempt = attempt >= MAX_ATTEMPTS; + const perConversationData = this.perConversationData.get(conversationId); await window.ConversationController.load(); @@ -334,6 +644,11 @@ export class ConversationJobQueue extends JobQueue { throw new Error(`Failed to find conversation ${conversationId}`); } + if (perConversationData?.retryAt && !shouldSendShowCaptcha(type)) { + // If we return this value, JobQueue will call retryJobOnQueueIdle for this job + return JOB_STATUS.NEEDS_RETRY; + } + let timeRemaining: number; let shouldContinue: boolean; let count = 0; @@ -354,10 +669,24 @@ export class ConversationJobQueue extends JobQueue { break; } - if (window.Signal.challengeHandler?.isRegistered(conversationId)) { + const isChallengeRegistered = + window.Signal.challengeHandler?.isRegistered(conversationId); + if (!isChallengeRegistered) { + this.unblockConversationRetries(conversationId); + } + + if (isChallengeRegistered && shouldSendShowCaptcha(type)) { if (this.isShuttingDown) { throw new Error("Shutting down, can't wait for captcha challenge."); } + + window.Signal.challengeHandler?.maybeSolve({ + conversationId, + reason: + 'conversationJobQueue.run/addWaiter(' + + `${conversation.idForLogging()}, ${type}, ${timestamp})`, + }); + log.info( 'captcha challenge is pending for this conversation; waiting at most 5m...' ); @@ -390,7 +719,7 @@ export class ConversationJobQueue extends JobQueue { log.warn( "Cancelling profile share, we don't want to wait for pending verification." ); - return; + return undefined; } if (this.isShuttingDown) { @@ -502,68 +831,91 @@ export class ConversationJobQueue extends JobQueue { ); } } - } catch (error: unknown) { - const untrustedUuids: Array = []; - const processError = (toProcess: unknown) => { + return undefined; + } catch (error: unknown) { + const untrustedServiceIds: Array = []; + + const processError = ( + toProcess: unknown + ): undefined | typeof JOB_STATUS.NEEDS_RETRY => { if (toProcess instanceof OutgoingIdentityKeyError) { const failedConversation = window.ConversationController.getOrCreate( toProcess.identifier, 'private' ); strictAssert(failedConversation, 'Conversation should be created'); - const uuid = failedConversation.get('uuid'); - if (!uuid) { + const serviceId = failedConversation.getServiceId(); + if (!serviceId) { log.error( - `failedConversation: Conversation ${failedConversation.idForLogging()} missing UUID!` + `failedConversation: Conversation ${failedConversation.idForLogging()} missing serviceId!` ); - return; + return undefined; } - untrustedUuids.push(uuid); + untrustedServiceIds.push(serviceId); } else if (toProcess instanceof SendMessageChallengeError) { - void window.Signal.challengeHandler?.register( - { - conversationId, - createdAt: Date.now(), - retryAt: toProcess.retryAt, - token: toProcess.data?.token, - reason: - 'conversationJobQueue.run(' + - `${conversation.idForLogging()}, ${type}, ${timestamp})`, - }, - toProcess.data + const silent = !shouldSendShowCaptcha(type); + + drop( + window.Signal.challengeHandler?.register( + { + conversationId, + createdAt: Date.now(), + retryAt: toProcess.retryAt, + token: toProcess.data?.token, + reason: + 'conversationJobQueue.run(' + + `${conversation.idForLogging()}, ${type}, ${timestamp})`, + silent, + }, + toProcess.data + ) ); + + if (silent) { + this.captureRetryAt(conversationId, toProcess.retryAt); + return JOB_STATUS.NEEDS_RETRY; + } } + return undefined; }; - processError(error); - if (error instanceof SendMessageProtoError) { - (error.errors || []).forEach(processError); + const value = processError(error); + if (value) { + return value; } - if (untrustedUuids.length) { + if (error instanceof SendMessageProtoError) { + const values = (error.errors || []).map(processError); + const innerValue = values.find(item => Boolean(item)); + if (innerValue) { + return innerValue; + } + } + + if (untrustedServiceIds.length) { if (type === jobSet.ProfileKey) { log.warn( - `Cancelling profile share, since there were ${untrustedUuids.length} untrusted send targets.` + `Cancelling profile share, since there were ${untrustedServiceIds.length} untrusted send targets.` ); - return; + return undefined; } if (type === jobSet.Receipts) { log.warn( - `Cancelling receipt send, since there were ${untrustedUuids.length} untrusted send targets.` + `Cancelling receipt send, since there were ${untrustedServiceIds.length} untrusted send targets.` ); - return; + return undefined; } log.error( - `Send failed because ${untrustedUuids.length} conversation(s) were untrusted. Adding to verification list.` + `Send failed because ${untrustedServiceIds.length} conversation(s) were untrusted. Adding to verification list.` ); window.reduxActions.conversations.conversationStoppedByMissingVerification( { conversationId: conversation.id, - untrustedUuids, + untrustedServiceIds, } ); } diff --git a/ts/jobs/helpers/addReportSpamJob.ts b/ts/jobs/helpers/addReportSpamJob.ts index 836522634d..8dfd8de19f 100644 --- a/ts/jobs/helpers/addReportSpamJob.ts +++ b/ts/jobs/helpers/addReportSpamJob.ts @@ -5,6 +5,7 @@ import { assertDev } from '../../util/assert'; import { isDirectConversation } from '../../util/whatTypeOfConversation'; import * as log from '../../logging/log'; import type { ConversationAttributesType } from '../../model-types.d'; +import { isAciString } from '../../util/isAciString'; import type { reportSpamJobQueue } from '../reportSpamJobQueue'; export async function addReportSpamJob({ @@ -13,7 +14,10 @@ export async function addReportSpamJob({ jobQueue, }: Readonly<{ conversation: Readonly< - Pick + Pick< + ConversationAttributesType, + 'id' | 'type' | 'serviceId' | 'reportingToken' + > >; getMessageServerGuidsForSpam: ( conversationId: string @@ -25,10 +29,10 @@ export async function addReportSpamJob({ 'addReportSpamJob: cannot report spam for non-direct conversations' ); - const { uuid } = conversation; - if (!uuid) { + const { serviceId: aci } = conversation; + if (!aci || !isAciString(aci)) { log.info( - 'addReportSpamJob got a conversation with no UUID, which the server does not support. Doing nothing' + 'addReportSpamJob got a conversation with no aci, which the server does not support. Doing nothing' ); return; } @@ -44,5 +48,5 @@ export async function addReportSpamJob({ return; } - await jobQueue.add({ uuid, serverGuids, token: conversation.reportingToken }); + await jobQueue.add({ aci, serverGuids, token: conversation.reportingToken }); } diff --git a/ts/jobs/helpers/getUntrustedConversationUuids.ts b/ts/jobs/helpers/getUntrustedConversationServiceIds.ts similarity index 59% rename from ts/jobs/helpers/getUntrustedConversationUuids.ts rename to ts/jobs/helpers/getUntrustedConversationServiceIds.ts index 9dba77eeda..e8e55d6a05 100644 --- a/ts/jobs/helpers/getUntrustedConversationUuids.ts +++ b/ts/jobs/helpers/getUntrustedConversationServiceIds.ts @@ -3,11 +3,11 @@ import { isNotNil } from '../../util/isNotNil'; import * as log from '../../logging/log'; -import type { UUIDStringType } from '../../types/UUID'; +import type { ServiceIdString } from '../../types/ServiceId'; -export function getUntrustedConversationUuids( +export function getUntrustedConversationServiceIds( recipients: ReadonlyArray -): Array { +): Array { return recipients .map(recipient => { const recipientConversation = window.ConversationController.getOrCreate( @@ -19,15 +19,15 @@ export function getUntrustedConversationUuids( return null; } - const uuid = recipientConversation.get('uuid'); - if (!uuid) { + const serviceId = recipientConversation.getServiceId(); + if (!serviceId) { log.warn( - `getUntrustedConversationUuids: Conversation ${recipientConversation.idForLogging()} had no UUID` + `getUntrustedConversationServiceIds: Conversation ${recipientConversation.idForLogging()} had no serviceId` ); return null; } - return uuid; + return serviceId; }) .filter(isNotNil); } diff --git a/ts/jobs/helpers/sendDeleteForEveryone.ts b/ts/jobs/helpers/sendDeleteForEveryone.ts index 447fe044d6..427d256271 100644 --- a/ts/jobs/helpers/sendDeleteForEveryone.ts +++ b/ts/jobs/helpers/sendDeleteForEveryone.ts @@ -23,20 +23,20 @@ import type { ConversationQueueJobBundle, DeleteForEveryoneJobData, } from '../conversationJobQueue'; -import { getUntrustedConversationUuids } from './getUntrustedConversationUuids'; +import { getUntrustedConversationServiceIds } from './getUntrustedConversationServiceIds'; import { handleMessageSend } from '../../util/handleMessageSend'; import { isConversationAccepted } from '../../util/isConversationAccepted'; import { isConversationUnregistered } from '../../util/isConversationUnregistered'; -import { getMessageById } from '../../messages/getMessageById'; +import { __DEPRECATED$getMessageById } from '../../messages/getMessageById'; import { isNotNil } from '../../util/isNotNil'; import type { CallbackResultType } from '../../textsecure/Types.d'; import type { MessageModel } from '../../models/messages'; import { SendMessageProtoError } from '../../textsecure/Errors'; import { strictAssert } from '../../util/assert'; import type { LoggerType } from '../../types/Logging'; +import type { ServiceIdString } from '../../types/ServiceId'; import { isStory } from '../../messages/helpers'; import { sendToGroup } from '../../util/sendToGroup'; -import { getTaggedConversationUuid } from '../../util/getConversationUuid'; export async function sendDeleteForEveryone( conversation: ConversationModel, @@ -59,7 +59,7 @@ export async function sendDeleteForEveryone( const logId = `sendDeleteForEveryone(${conversation.idForLogging()}, ${messageId})`; - const message = await getMessageById(messageId); + const message = await __DEPRECATED$getMessageById(messageId); if (!message) { log.error(`${logId}: Failed to fetch message. Failing job.`); return; @@ -91,16 +91,20 @@ export async function sendDeleteForEveryone( ); const recipients = deletedForEveryoneSendStatus ? getRecipients(deletedForEveryoneSendStatus) - : recipientsFromJob; + : recipientsFromJob + .map(recipient => { + return window.ConversationController.get(recipient)?.getServiceId(); + }) + .filter(isNotNil); - const untrustedUuids = getUntrustedConversationUuids(recipients); - if (untrustedUuids.length) { + const untrustedServiceIds = getUntrustedConversationServiceIds(recipients); + if (untrustedServiceIds.length) { window.reduxActions.conversations.conversationStoppedByMissingVerification({ conversationId: conversation.id, - untrustedUuids, + untrustedServiceIds, }); throw new Error( - `Delete for everyone blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.` + `Delete for everyone blocked because ${untrustedServiceIds.length} conversation(s) were untrusted. Failing this attempt.` ); } @@ -140,9 +144,7 @@ export async function sendDeleteForEveryone( proto.dataMessage ).finish(), destination: conversation.get('e164'), - destinationUuid: getTaggedConversationUuid( - conversation.attributes - ), + destinationServiceId: conversation.getServiceId(), expirationStartTimestamp: null, options: sendOptions, timestamp, @@ -191,9 +193,9 @@ export async function sendDeleteForEveryone( logId, messageIds, send: async sender => - sender.sendMessageToIdentifier({ + sender.sendMessageToServiceId({ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - identifier: conversation.getSendTarget()!, + serviceId: conversation.getSendTarget()!, messageText: undefined, attachments: [], deletedForEveryoneTimestamp: targetTimestamp, @@ -272,7 +274,7 @@ export async function sendDeleteForEveryone( function getRecipients( sendStatusByConversationId: Record -): Array { +): Array { return Object.entries(sendStatusByConversationId) .filter(([_, isSent]) => !isSent) .map(([conversationId]) => { @@ -286,7 +288,7 @@ function getRecipients( if (recipient.isBlocked()) { return null; } - return recipient.get('uuid'); + return recipient.getServiceId(); }) .filter(isNotNil); } @@ -301,7 +303,7 @@ async function updateMessageWithSuccessfulSends( deletedForEveryoneFailed: undefined, }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); return; @@ -311,8 +313,8 @@ async function updateMessageWithSuccessfulSends( ...message.get('deletedForEveryoneSendStatus'), }; - result.successfulIdentifiers?.forEach(identifier => { - const conversation = window.ConversationController.get(identifier); + result.successfulServiceIds?.forEach(serviceId => { + const conversation = window.ConversationController.get(serviceId); if (!conversation) { return; } @@ -324,7 +326,7 @@ async function updateMessageWithSuccessfulSends( deletedForEveryoneFailed: undefined, }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } @@ -340,6 +342,6 @@ async function updateMessageWithFailure( message.set({ deletedForEveryoneFailed: true }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } diff --git a/ts/jobs/helpers/sendDeleteStoryForEveryone.ts b/ts/jobs/helpers/sendDeleteStoryForEveryone.ts index 166e59fbee..b895e0bb94 100644 --- a/ts/jobs/helpers/sendDeleteStoryForEveryone.ts +++ b/ts/jobs/helpers/sendDeleteStoryForEveryone.ts @@ -16,11 +16,11 @@ import type { ConversationQueueJobBundle, DeleteStoryForEveryoneJobData, } from '../conversationJobQueue'; -import { getUntrustedConversationUuids } from './getUntrustedConversationUuids'; +import { getUntrustedConversationServiceIds } from './getUntrustedConversationServiceIds'; import { handleMessageSend } from '../../util/handleMessageSend'; import { isConversationAccepted } from '../../util/isConversationAccepted'; import { isConversationUnregistered } from '../../util/isConversationUnregistered'; -import { getMessageById } from '../../messages/getMessageById'; +import { __DEPRECATED$getMessageById } from '../../messages/getMessageById'; import { isNotNil } from '../../util/isNotNil'; import type { CallbackResultType } from '../../textsecure/Types.d'; import type { MessageModel } from '../../models/messages'; @@ -45,7 +45,7 @@ export async function sendDeleteStoryForEveryone( const logId = `sendDeleteStoryForEveryone(${storyId})`; - const message = await getMessageById(storyId); + const message = await __DEPRECATED$getMessageById(storyId); if (!message) { log.error(`${logId}: Failed to fetch message. Failing job.`); return; @@ -82,14 +82,14 @@ export async function sendDeleteStoryForEveryone( .filter(([_, isSent]) => !isSent) .map(([conversationId]) => conversationId); - const untrustedUuids = getUntrustedConversationUuids(recipientIds); - if (untrustedUuids.length) { + const untrustedServiceIds = getUntrustedConversationServiceIds(recipientIds); + if (untrustedServiceIds.length) { window.reduxActions.conversations.conversationStoppedByMissingVerification({ conversationId: ourConversation.id, - untrustedUuids, + untrustedServiceIds, }); throw new Error( - `Delete for everyone blocked because ${untrustedUuids.length} ` + + `Delete for everyone blocked because ${untrustedServiceIds.length} ` + 'conversation(s) were untrusted. Failing this attempt.' ); } @@ -171,10 +171,12 @@ export async function sendDeleteStoryForEveryone( }); try { + const serviceId = conversation.getSendTarget(); + strictAssert(serviceId, 'conversation has no service id'); + await handleMessageSend( - messaging.sendMessageToIdentifier({ - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - identifier: conversation.getSendTarget()!, + messaging.sendMessageToServiceId({ + serviceId, messageText: undefined, attachments: [], deletedForEveryoneTimestamp: targetTimestamp, @@ -200,7 +202,7 @@ export async function sendDeleteStoryForEveryone( await updateMessageWithSuccessfulSends(message, { dataMessage: undefined, editMessage: undefined, - successfulIdentifiers: [conversation.id], + successfulServiceIds: [serviceId], }); } catch (error: unknown) { if (error instanceof SendMessageProtoError) { @@ -231,19 +233,17 @@ export async function sendDeleteStoryForEveryone( syncMessage: true, }); - const destinationUuid = ourConversation - .getCheckedUuid('deleteStoryForEveryone') - .toString(); + const destinationServiceId = ourConversation.getCheckedServiceId( + 'deleteStoryForEveryone' + ); // Sync message for other devices await handleMessageSend( messaging.sendSyncMessage({ destination: undefined, - destinationUuid: { - aci: destinationUuid, - }, + destinationServiceId, storyMessageRecipients: updatedStoryRecipients?.map( - ({ destinationUuid: legacyDestinationUuid, ...rest }) => { + ({ destinationServiceId: legacyDestinationUuid, ...rest }) => { return { // The field was renamed. legacyDestinationUuid, @@ -278,7 +278,7 @@ async function updateMessageWithSuccessfulSends( deletedForEveryoneFailed: undefined, }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); return; @@ -288,8 +288,8 @@ async function updateMessageWithSuccessfulSends( ...message.get('deletedForEveryoneSendStatus'), }; - result.successfulIdentifiers?.forEach(identifier => { - const conversation = window.ConversationController.get(identifier); + result.successfulServiceIds?.forEach(serviceId => { + const conversation = window.ConversationController.get(serviceId); if (!conversation) { return; } @@ -301,7 +301,7 @@ async function updateMessageWithSuccessfulSends( deletedForEveryoneFailed: undefined, }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } @@ -317,6 +317,6 @@ async function updateMessageWithFailure( message.set({ deletedForEveryoneFailed: true }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } diff --git a/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts b/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts index bce04da5fb..8c8f195151 100644 --- a/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts +++ b/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts @@ -20,7 +20,6 @@ import { handleMessageSend } from '../../util/handleMessageSend'; import { isConversationAccepted } from '../../util/isConversationAccepted'; import { isConversationUnregistered } from '../../util/isConversationUnregistered'; import { DurationInSeconds } from '../../util/durations'; -import { getTaggedConversationUuid } from '../../util/getConversationUuid'; export async function sendDirectExpirationTimerUpdate( conversation: ConversationModel, @@ -47,14 +46,12 @@ export async function sendDirectExpirationTimerUpdate( } if (conversation.isUntrusted()) { - const uuid = conversation - .getCheckedUuid( - 'Expiration timer send blocked: untrusted and missing uuid!' - ) - .toString(); + const serviceId = conversation.getCheckedServiceId( + 'Expiration timer send blocked: untrusted and missing serviceId!' + ); window.reduxActions.conversations.conversationStoppedByMissingVerification({ conversationId: conversation.id, - untrustedUuids: [uuid], + untrustedServiceIds: [serviceId], }); throw new Error( 'Expiration timer send blocked because conversation is untrusted. Failing this attempt.' @@ -108,7 +105,7 @@ export async function sendDirectExpirationTimerUpdate( proto.dataMessage ).finish(), destination: conversation.get('e164'), - destinationUuid: getTaggedConversationUuid(conversation.attributes), + destinationServiceId: conversation.getServiceId(), expirationStartTimestamp: null, options: sendOptions, timestamp, @@ -143,7 +140,7 @@ export async function sendDirectExpirationTimerUpdate( send: async sender => sender.sendIndividualProto({ contentHint, - identifier: conversation.getSendTarget(), + serviceId: conversation.getSendTarget(), options: sendOptions, proto, timestamp, diff --git a/ts/jobs/helpers/sendGroupUpdate.ts b/ts/jobs/helpers/sendGroupUpdate.ts index da1819c4cd..7b61d49334 100644 --- a/ts/jobs/helpers/sendGroupUpdate.ts +++ b/ts/jobs/helpers/sendGroupUpdate.ts @@ -11,6 +11,7 @@ import { import { wrapWithSyncMessageSend } from '../../util/wrapWithSyncMessageSend'; import * as Bytes from '../../Bytes'; import { strictAssert } from '../../util/assert'; +import { isNotNil } from '../../util/isNotNil'; import { ourProfileKeyService } from '../../services/ourProfileKey'; import type { ConversationModel } from '../../models/conversations'; @@ -19,7 +20,7 @@ import type { GroupUpdateJobData, ConversationQueueJobBundle, } from '../conversationJobQueue'; -import { getUntrustedConversationUuids } from './getUntrustedConversationUuids'; +import { getUntrustedConversationServiceIds } from './getUntrustedConversationServiceIds'; import { sendToGroup } from '../../util/sendToGroup'; // Note: because we don't have a recipient map, if some sends fail, we will resend this @@ -54,35 +55,37 @@ export async function sendGroupUpdate( const { groupChangeBase64, recipients: jobRecipients, revision } = data; - const recipients = jobRecipients.filter(id => { - const recipient = window.ConversationController.get(id); - if (!recipient) { - return false; - } - if (recipient.isUnregistered()) { - log.warn( - `${logId}: dropping unregistered recipient ${recipient.idForLogging()}` - ); - return false; - } - if (recipient.isBlocked()) { - log.warn( - `${logId}: dropping blocked recipient ${recipient.idForLogging()}` - ); - return false; - } + const recipients = jobRecipients + .map(id => { + const recipient = window.ConversationController.get(id); + if (!recipient) { + return undefined; + } + if (recipient.isUnregistered()) { + log.warn( + `${logId}: dropping unregistered recipient ${recipient.idForLogging()}` + ); + return undefined; + } + if (recipient.isBlocked()) { + log.warn( + `${logId}: dropping blocked recipient ${recipient.idForLogging()}` + ); + return undefined; + } - return true; - }); + return recipient.getSendTarget(); + }) + .filter(isNotNil); - const untrustedUuids = getUntrustedConversationUuids(recipients); - if (untrustedUuids.length) { + const untrustedServiceIds = getUntrustedConversationServiceIds(recipients); + if (untrustedServiceIds.length) { window.reduxActions.conversations.conversationStoppedByMissingVerification({ conversationId: conversation.id, - untrustedUuids, + untrustedServiceIds, }); throw new Error( - `Group update blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.` + `Group update blocked because ${untrustedServiceIds.length} conversation(s) were untrusted. Failing this attempt.` ); } diff --git a/ts/jobs/helpers/sendNormalMessage.ts b/ts/jobs/helpers/sendNormalMessage.ts index c74ffae695..d224fd9905 100644 --- a/ts/jobs/helpers/sendNormalMessage.ts +++ b/ts/jobs/helpers/sendNormalMessage.ts @@ -7,7 +7,7 @@ import PQueue from 'p-queue'; import * as Errors from '../../types/errors'; import { strictAssert } from '../../util/assert'; import type { MessageModel } from '../../models/messages'; -import { getMessageById } from '../../messages/getMessageById'; +import { __DEPRECATED$getMessageById } from '../../messages/getMessageById'; import type { ConversationModel } from '../../models/conversations'; import { isGroup, isGroupV2, isMe } from '../../util/whatTypeOfConversation'; import { getSendOptions } from '../../util/getSendOptions'; @@ -15,7 +15,6 @@ import { SignalService as Proto } from '../../protobuf'; import { handleMessageSend } from '../../util/handleMessageSend'; import { findAndFormatContact } from '../../util/findAndFormatContact'; import { uploadAttachment } from '../../util/uploadAttachment'; -import { getMessageSentTimestamp } from '../../util/getMessageSentTimestamp'; import type { CallbackResultType } from '../../textsecure/Types.d'; import { isSent } from '../../messages/MessageSendState'; import { isOutgoing, canReact } from '../../state/selectors/message'; @@ -31,7 +30,8 @@ import type { UploadedAttachmentType, AttachmentWithHydratedData, } from '../../types/Attachment'; -import { LONG_MESSAGE, MIMETypeToString } from '../../types/MIME'; +import { copyCdnFields } from '../../util/attachments'; +import { LONG_MESSAGE } from '../../types/MIME'; import type { RawBodyRange } from '../../types/BodyRange'; import type { EmbeddedContactWithHydratedAvatar, @@ -50,8 +50,15 @@ import { isConversationUnregistered } from '../../util/isConversationUnregistere import { isConversationAccepted } from '../../util/isConversationAccepted'; import { sendToGroup } from '../../util/sendToGroup'; import type { DurationInSeconds } from '../../util/durations'; -import type { UUIDStringType } from '../../types/UUID'; +import type { ServiceIdString } from '../../types/ServiceId'; +import { normalizeAci } from '../../util/normalizeAci'; import * as Bytes from '../../Bytes'; +import { + getPropForTimestamp, + getTargetOfThisEditTimestamp, + setPropForTimestamp, +} from '../../util/editHelpers'; +import { getMessageSentTimestamp } from '../../util/getMessageSentTimestamp'; const LONG_ATTACHMENT_LIMIT = 2048; const MAX_CONCURRENT_ATTACHMENT_UPLOADS = 5; @@ -70,7 +77,7 @@ export async function sendNormalMessage( const { Message } = window.Signal.Types; const { messageId, revision, editedMessageTimestamp } = data; - const message = await getMessageById(messageId); + const message = await __DEPRECATED$getMessageById(messageId); if (!message) { log.info( `message ${messageId} was not found, maybe because it was deleted. Giving up on sending it` @@ -98,6 +105,20 @@ export async function sendNormalMessage( return; } + // The original timestamp for this message + const messageTimestamp = getMessageSentTimestamp(message.attributes, { + includeEdits: false, + log, + }); + // The timestamp for the thing we're sending now, whether a first send or an edit + const targetTimestamp = editedMessageTimestamp || messageTimestamp; + // The timestamp identifying the target of this edit; could be the original timestamp + // or the most recent edit prior to this one + const targetOfThisEditTimestamp = getTargetOfThisEditTimestamp({ + message, + targetTimestamp, + }); + let messageSendErrors: Array = []; // We don't want to save errors on messages unless we're giving up. If it's our @@ -116,9 +137,11 @@ export async function sendNormalMessage( if (!shouldContinue) { log.info(`message ${messageId} ran out of time. Giving up on sending it`); - await markMessageFailed(message, [ - new Error('Message send ran out of time'), - ]); + await markMessageFailed({ + message, + errors: [new Error('Message send ran out of time')], + targetTimestamp, + }); return; } @@ -131,29 +154,30 @@ export async function sendNormalMessage( try { const { - allRecipientIdentifiers, - recipientIdentifiersWithoutMe, - sentRecipientIdentifiers, - untrustedUuids, + allRecipientServiceIds, + recipientServiceIdsWithoutMe, + sentRecipientServiceIds, + untrustedServiceIds, } = getMessageRecipients({ log, message, conversation, + targetTimestamp, }); - if (untrustedUuids.length) { + if (untrustedServiceIds.length) { window.reduxActions.conversations.conversationStoppedByMissingVerification( { conversationId: conversation.id, - untrustedUuids, + untrustedServiceIds, } ); throw new Error( - `Message ${messageId} sending blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.` + `Message ${messageId} sending blocked because ${untrustedServiceIds.length} conversation(s) were untrusted. Failing this attempt.` ); } - if (!allRecipientIdentifiers.length) { + if (!allRecipientServiceIds.length) { log.warn( `trying to send message ${messageId} but it looks like it was already sent to everyone. This is unexpected, but we're giving up` ); @@ -167,14 +191,13 @@ export async function sendNormalMessage( deletedForEveryoneTimestamp, expireTimer, bodyRanges, - messageTimestamp, preview, quote, reaction, sticker, storyMessage, storyContext, - } = await getMessageSendData({ log, message }); + } = await getMessageSendData({ log, message, targetTimestamp }); if (reaction) { strictAssert( @@ -195,25 +218,37 @@ export async function sendNormalMessage( log.info( `could not react to ${messageId}. Removing this pending reaction` ); - await markMessageFailed(message, [ - new Error('Could not react to story'), - ]); + await markMessageFailed({ + message, + errors: [new Error('Could not react to story')], + targetTimestamp, + }); return; } } + log.info( + 'Sending normal message;', + `editedMessageTimestamp=${editedMessageTimestamp},`, + `storyMessage=${Boolean(storyMessage)}` + ); + let messageSendPromise: Promise; - if (recipientIdentifiersWithoutMe.length === 0) { + if (recipientServiceIdsWithoutMe.length === 0) { if ( !isMe(conversation.attributes) && !isGroup(conversation.attributes) && - sentRecipientIdentifiers.length === 0 + sentRecipientServiceIds.length === 0 ) { log.info( 'No recipients; not sending to ourselves or to group, and no successful sends. Failing job.' ); - void markMessageFailed(message, [new Error('No valid recipients')]); + void markMessageFailed({ + message, + errors: [new Error('No valid recipients')], + targetTimestamp, + }); return; } @@ -227,21 +262,27 @@ export async function sendNormalMessage( bodyRanges, contact, deletedForEveryoneTimestamp, - editedMessageTimestamp, expireTimer, groupV2: conversation.getGroupV2Info({ - members: recipientIdentifiersWithoutMe, + members: recipientServiceIdsWithoutMe, }), preview, profileKey, quote, - recipients: allRecipientIdentifiers, + recipients: allRecipientServiceIds, sticker, storyContext, - timestamp: messageTimestamp, + targetTimestampForEdit: editedMessageTimestamp + ? targetOfThisEditTimestamp + : undefined, + timestamp: targetTimestamp, reaction, }); - messageSendPromise = message.sendSyncMessageOnly(dataMessage, saveErrors); + messageSendPromise = message.sendSyncMessageOnly({ + dataMessage, + saveErrors, + targetTimestamp, + }); } else { const conversationType = conversation.get('type'); const sendOptions = await getSendOptions(conversation.attributes); @@ -255,7 +296,7 @@ export async function sendNormalMessage( } const groupV2Info = conversation.getGroupV2Info({ - members: recipientIdentifiersWithoutMe, + members: recipientServiceIdsWithoutMe, }); if (groupV2Info && isNumber(revision)) { groupV2Info.revision = revision; @@ -273,7 +314,6 @@ export async function sendNormalMessage( bodyRanges, contact, deletedForEveryoneTimestamp, - editedMessageTimestamp, expireTimer, groupV2: groupV2Info, messageText: body, @@ -283,7 +323,10 @@ export async function sendNormalMessage( sticker, storyContext, reaction, - timestamp: messageTimestamp, + targetTimestampForEdit: editedMessageTimestamp + ? targetOfThisEditTimestamp + : undefined, + timestamp: targetTimestamp, }, messageId, sendOptions, @@ -298,39 +341,46 @@ export async function sendNormalMessage( log.info( `conversation ${conversation.idForLogging()} is not accepted; refusing to send` ); - void markMessageFailed(message, [ - new Error('Message request was not accepted'), - ]); + void markMessageFailed({ + message, + errors: [new Error('Message request was not accepted')], + targetTimestamp, + }); return; } if (isConversationUnregistered(conversation.attributes)) { log.info( `conversation ${conversation.idForLogging()} is unregistered; refusing to send` ); - void markMessageFailed(message, [ - new Error('Contact no longer has a Signal account'), - ]); + void markMessageFailed({ + message, + errors: [new Error('Contact no longer has a Signal account')], + targetTimestamp, + }); return; } if (conversation.isBlocked()) { log.info( `conversation ${conversation.idForLogging()} is blocked; refusing to send` ); - void markMessageFailed(message, [new Error('Contact is blocked')]); + void markMessageFailed({ + message, + errors: [new Error('Contact is blocked')], + targetTimestamp, + }); return; } log.info('sending direct message'); - innerPromise = messaging.sendMessageToIdentifier({ + innerPromise = messaging.sendMessageToServiceId({ attachments, bodyRanges, contact, contentHint: ContentHint.RESENDABLE, deletedForEveryoneTimestamp, - editedMessageTimestamp, expireTimer, groupId: undefined, - identifier: recipientIdentifiersWithoutMe[0], + serviceId: recipientServiceIdsWithoutMe[0], messageText: body, options: sendOptions, preview, @@ -339,20 +389,24 @@ export async function sendNormalMessage( sticker, storyContext, reaction, - timestamp: messageTimestamp, + targetTimestampForEdit: editedMessageTimestamp + ? targetOfThisEditTimestamp + : undefined, + timestamp: targetTimestamp, // Note: 1:1 story replies should not set story=true - they aren't group sends urgent: true, includePniSignatureMessage: true, }); } - messageSendPromise = message.send( - handleMessageSend(innerPromise, { + messageSendPromise = message.send({ + promise: handleMessageSend(innerPromise, { messageIds: [messageId], sendType: 'message', }), - saveErrors - ); + saveErrors, + targetTimestamp, + }); // Because message.send swallows and processes errors, we'll await the inner promise // to get the SendMessageProtoError, which gives us information upstream @@ -375,7 +429,12 @@ export async function sendNormalMessage( await messageSendPromise; const didFullySend = - !messageSendErrors.length || didSendToEveryone(message); + !messageSendErrors.length || + didSendToEveryone({ + log, + message, + targetTimestamp: editedMessageTimestamp || messageTimestamp, + }); if (!didFullySend) { throw new Error('message did not fully send'); } @@ -385,7 +444,12 @@ export async function sendNormalMessage( errors, isFinalAttempt, log, - markFailed: () => markMessageFailed(message, messageSendErrors), + markFailed: () => + markMessageFailed({ + message, + errors: messageSendErrors, + targetTimestamp, + }), timeRemaining, // In the case of a failed group send thrownError will not be SentMessageProtoError, // but we should have been able to harvest the original error. In the Note to Self @@ -400,24 +464,34 @@ function getMessageRecipients({ log, conversation, message, + targetTimestamp, }: Readonly<{ log: LoggerType; conversation: ConversationModel; message: MessageModel; + targetTimestamp: number; }>): { - allRecipientIdentifiers: Array; - recipientIdentifiersWithoutMe: Array; - sentRecipientIdentifiers: Array; - untrustedUuids: Array; + allRecipientServiceIds: Array; + recipientServiceIdsWithoutMe: Array; + sentRecipientServiceIds: Array; + untrustedServiceIds: Array; } { - const allRecipientIdentifiers: Array = []; - const recipientIdentifiersWithoutMe: Array = []; - const untrustedUuids: Array = []; - const sentRecipientIdentifiers: Array = []; + const allRecipientServiceIds: Array = []; + const recipientServiceIdsWithoutMe: Array = []; + const untrustedServiceIds: Array = []; + const sentRecipientServiceIds: Array = []; const currentConversationRecipients = conversation.getMemberConversationIds(); - Object.entries(message.get('sendStateByConversationId') || {}).forEach( + const sendStateByConversationId = + getPropForTimestamp({ + log, + message, + prop: 'sendStateByConversationId', + targetTimestamp, + }) || {}; + + Object.entries(sendStateByConversationId).forEach( ([recipientConversationId, sendState]) => { const recipient = window.ConversationController.get( recipientConversationId @@ -436,14 +510,14 @@ function getMessageRecipients({ } if (recipient.isUntrusted()) { - const uuid = recipient.get('uuid'); - if (!uuid) { + const serviceId = recipient.getServiceId(); + if (!serviceId) { log.error( - `sendNormalMessage/getMessageRecipients: Untrusted conversation ${recipient.idForLogging()} missing UUID.` + `sendNormalMessage/getMessageRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.` ); return; } - untrustedUuids.push(uuid); + untrustedServiceIds.push(serviceId); return; } if (recipient.isUnregistered()) { @@ -459,31 +533,33 @@ function getMessageRecipients({ } if (isSent(sendState.status)) { - sentRecipientIdentifiers.push(recipientIdentifier); + sentRecipientServiceIds.push(recipientIdentifier); return; } - allRecipientIdentifiers.push(recipientIdentifier); + allRecipientServiceIds.push(recipientIdentifier); if (!isRecipientMe) { - recipientIdentifiersWithoutMe.push(recipientIdentifier); + recipientServiceIdsWithoutMe.push(recipientIdentifier); } } ); return { - allRecipientIdentifiers, - recipientIdentifiersWithoutMe, - sentRecipientIdentifiers, - untrustedUuids, + allRecipientServiceIds, + recipientServiceIdsWithoutMe, + sentRecipientServiceIds, + untrustedServiceIds, }; } async function getMessageSendData({ log, message, + targetTimestamp, }: Readonly<{ log: LoggerType; message: MessageModel; + targetTimestamp: number; }>): Promise<{ attachments: Array; body: undefined | string; @@ -491,7 +567,6 @@ async function getMessageSendData({ deletedForEveryoneTimestamp: undefined | number; expireTimer: undefined | DurationInSeconds; bodyRanges: undefined | ReadonlyArray; - messageTimestamp: number; preview: Array | undefined; quote: OutgoingQuoteType | undefined; sticker: OutgoingStickerType | undefined; @@ -499,25 +574,22 @@ async function getMessageSendData({ storyMessage?: MessageModel; storyContext?: StoryContextType; }> { - const editMessageTimestamp = message.get('editMessageTimestamp'); - - const mainMessageTimestamp = getMessageSentTimestamp(message.attributes, { - includeEdits: false, - log, - }); - const messageTimestamp = editMessageTimestamp || mainMessageTimestamp; - const storyId = message.get('storyId'); // Figure out if we need to upload message body as an attachment. - let body = message.get('body'); + let body = getPropForTimestamp({ + log, + message, + prop: 'body', + targetTimestamp, + }); let maybeLongAttachment: AttachmentWithHydratedData | undefined; if (body && body.length > LONG_ATTACHMENT_LIMIT) { const data = Bytes.fromString(body); maybeLongAttachment = { contentType: LONG_MESSAGE, - fileName: `long-message-${messageTimestamp}.txt`, + fileName: `long-message-${targetTimestamp}.txt`, data, size: data.byteLength, }; @@ -528,6 +600,13 @@ async function getMessageSendData({ concurrency: MAX_CONCURRENT_ATTACHMENT_UPLOADS, }); + const preUploadAttachments = + getPropForTimestamp({ + log, + message, + prop: 'attachments', + targetTimestamp, + }) || []; const [ uploadedAttachments, maybeUploadedLongAttachment, @@ -538,26 +617,54 @@ async function getMessageSendData({ storyMessage, ] = await Promise.all([ uploadQueue.addAll( - (message.get('attachments') ?? []).map( - attachment => () => uploadSingleAttachment(message, attachment) + preUploadAttachments.map( + attachment => () => + uploadSingleAttachment({ + attachment, + log, + message, + targetTimestamp, + }) ) ), uploadQueue.add(async () => maybeLongAttachment ? uploadAttachment(maybeLongAttachment) : undefined ), uploadMessageContacts(message, uploadQueue), - uploadMessagePreviews(message, uploadQueue), - uploadMessageQuote(message, uploadQueue), + uploadMessagePreviews({ + log, + message, + targetTimestamp, + uploadQueue, + }), + uploadMessageQuote({ + log, + message, + targetTimestamp, + uploadQueue, + }), uploadMessageSticker(message, uploadQueue), - storyId ? getMessageById(storyId) : undefined, + storyId ? __DEPRECATED$getMessageById(storyId) : undefined, ]); // Save message after uploading attachments await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); const storyReaction = message.get('storyReaction'); + const storySourceServiceId = storyMessage?.get('sourceServiceId'); + + let reactionForSend: ReactionType | undefined; + if (storyReaction) { + const { targetAuthorAci, ...restOfReaction } = storyReaction; + + reactionForSend = { + ...restOfReaction, + targetAuthorAci, + remove: false, + }; + } return { attachments: [ @@ -568,32 +675,42 @@ async function getMessageSendData({ contact, deletedForEveryoneTimestamp: message.get('deletedForEveryoneTimestamp'), expireTimer: message.get('expireTimer'), - // TODO: we want filtration here if feature flag doesn't allow format/spoiler sends - bodyRanges: message.get('bodyRanges'), - messageTimestamp, + bodyRanges: getPropForTimestamp({ + log, + message, + prop: 'bodyRanges', + targetTimestamp, + }), preview, quote, - reaction: storyReaction - ? { - ...storyReaction, - remove: false, - } - : undefined, + reaction: reactionForSend, sticker, storyMessage, storyContext: storyMessage ? { - authorUuid: storyMessage.get('sourceUuid'), + authorAci: storySourceServiceId + ? normalizeAci( + storySourceServiceId, + 'sendNormalMessage.storyContext.authorAci' + ) + : undefined, timestamp: storyMessage.get('sent_at'), } : undefined, }; } -async function uploadSingleAttachment( - message: MessageModel, - attachment: AttachmentType -): Promise { +async function uploadSingleAttachment({ + attachment, + log, + message, + targetTimestamp, +}: { + attachment: AttachmentType; + log: LoggerType; + message: MessageModel; + targetTimestamp: number; +}): Promise { const { loadAttachmentData } = window.Signal.Migrations; const withData = await loadAttachmentData(attachment); @@ -601,7 +718,12 @@ async function uploadSingleAttachment( // Add digest to the attachment const logId = `uploadSingleAttachment(${message.idForLogging()}`; - const oldAttachments = message.get('attachments'); + const oldAttachments = getPropForTimestamp({ + log, + message, + prop: 'attachments', + targetTimestamp, + }); strictAssert( oldAttachments !== undefined, `${logId}: Attachment was uploaded, but message doesn't ` + @@ -615,26 +737,47 @@ async function uploadSingleAttachment( ); const newAttachments = [...oldAttachments]; - newAttachments[index].digest = Bytes.toBase64(uploaded.digest); + newAttachments[index] = { + ...newAttachments[index], + ...copyCdnFields(uploaded), + }; - message.set('attachments', newAttachments); + setPropForTimestamp({ + log, + message, + prop: 'attachments', + targetTimestamp, + value: newAttachments, + }); return uploaded; } -async function uploadMessageQuote( - message: MessageModel, - uploadQueue: PQueue -): Promise { +async function uploadMessageQuote({ + log, + message, + targetTimestamp, + uploadQueue, +}: { + log: LoggerType; + message: MessageModel; + targetTimestamp: number; + uploadQueue: PQueue; +}): Promise { const { loadQuoteData } = window.Signal.Migrations; // We don't update the caches here because (1) we expect the caches to be populated // on initial send, so they should be there in the 99% case (2) if you're retrying // a failed message across restarts, we don't touch the cache for simplicity. If // sends are failing, let's not add the complication of a cache. + const startingQuote = getPropForTimestamp({ + log, + message, + prop: 'quote', + targetTimestamp, + }); const loadedQuote = - message.cachedOutgoingQuoteData || - (await loadQuoteData(message.get('quote'))); + message.cachedOutgoingQuoteData || (await loadQuoteData(startingQuote)); if (!loadedQuote) { return undefined; @@ -653,7 +796,7 @@ async function uploadMessageQuote( const uploaded = await uploadAttachment(thumbnail); return { - contentType: MIMETypeToString(thumbnail.contentType), + contentType: attachment.contentType, fileName: attachment.fileName, thumbnail: uploaded, }; @@ -663,7 +806,12 @@ async function uploadMessageQuote( // Update message with attachment digests const logId = `uploadMessageQuote(${message.idForLogging()}`; - const oldQuote = message.get('quote'); + const oldQuote = getPropForTimestamp({ + log, + message, + prop: 'quote', + targetTimestamp, + }); strictAssert(oldQuote, `${logId}: Quote is gone after upload`); const newQuote = { @@ -685,41 +833,60 @@ async function uploadMessageQuote( const attachmentAfterThumbnailUpload = attachmentsAfterThumbnailUpload[index]; - const digest = attachmentAfterThumbnailUpload.thumbnail - ? Bytes.toBase64(attachmentAfterThumbnailUpload.thumbnail.digest) - : undefined; return { ...attachment, thumbnail: { ...attachment.thumbnail, - digest, + ...copyCdnFields(attachmentAfterThumbnailUpload.thumbnail), }, }; }), }; - message.set('quote', newQuote); + setPropForTimestamp({ + log, + message, + prop: 'quote', + targetTimestamp, + value: newQuote, + }); return { isGiftBadge: loadedQuote.isGiftBadge, id: loadedQuote.id, - authorUuid: loadedQuote.authorUuid, + authorAci: loadedQuote.authorAci + ? normalizeAci(loadedQuote.authorAci, 'sendNormalMessage.quote.authorAci') + : undefined, text: loadedQuote.text, bodyRanges: loadedQuote.bodyRanges, attachments: attachmentsAfterThumbnailUpload, }; } -async function uploadMessagePreviews( - message: MessageModel, - uploadQueue: PQueue -): Promise | undefined> { +async function uploadMessagePreviews({ + log, + message, + targetTimestamp, + uploadQueue, +}: { + log: LoggerType; + message: MessageModel; + targetTimestamp: number; + uploadQueue: PQueue; +}): Promise | undefined> { const { loadPreviewData } = window.Signal.Migrations; // See uploadMessageQuote for comment on how we do caching for these // attachments. + const startingPreview = getPropForTimestamp({ + log, + message, + prop: 'preview', + targetTimestamp, + }); + const loadedPreviews = message.cachedOutgoingPreviewData || - (await loadPreviewData(message.get('preview'))); + (await loadPreviewData(startingPreview)); if (!loadedPreviews) { return undefined; @@ -750,7 +917,12 @@ async function uploadMessagePreviews( // Update message with attachment digests const logId = `uploadMessagePreviews(${message.idForLogging()}`; - const oldPreview = message.get('preview'); + const oldPreview = getPropForTimestamp({ + log, + message, + prop: 'preview', + targetTimestamp, + }); strictAssert(oldPreview, `${logId}: Link preview is gone after upload`); const newPreview = oldPreview.map((preview, index) => { @@ -768,11 +940,18 @@ async function uploadMessagePreviews( ...preview, image: { ...preview.image, - digest: Bytes.toBase64(uploaded.image.digest), + ...copyCdnFields(uploaded.image), }, }; }); - message.set('preview', newPreview); + + setPropForTimestamp({ + log, + message, + prop: 'preview', + targetTimestamp, + value: newPreview, + }); return uploadedPreviews; } @@ -814,7 +993,7 @@ async function uploadMessageSticker( ...existingSticker, data: { ...existingSticker.data, - digest: Bytes.toBase64(uploaded.digest), + ...copyCdnFields(uploaded), }, }); @@ -902,7 +1081,7 @@ async function uploadMessageContacts( ...contact.avatar, avatar: { ...contact.avatar.avatar, - digest: Bytes.toBase64(uploaded.avatar.avatar.digest), + ...copyCdnFields(uploaded.avatar.avatar), }, }, }; @@ -912,20 +1091,38 @@ async function uploadMessageContacts( return uploadedContacts; } -async function markMessageFailed( - message: MessageModel, - errors: Array -): Promise { - message.markFailed(); +async function markMessageFailed({ + errors, + message, + targetTimestamp, +}: { + errors: Array; + message: MessageModel; + targetTimestamp: number; +}): Promise { + message.markFailed(targetTimestamp); void message.saveErrors(errors, { skipSave: true }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } -function didSendToEveryone(message: Readonly): boolean { +function didSendToEveryone({ + log, + message, + targetTimestamp, +}: { + log: LoggerType; + message: MessageModel; + targetTimestamp: number; +}): boolean { const sendStateByConversationId = - message.get('sendStateByConversationId') || {}; + getPropForTimestamp({ + log, + message, + prop: 'sendStateByConversationId', + targetTimestamp, + }) || {}; return Object.values(sendStateByConversationId).every(sendState => isSent(sendState.status) ); diff --git a/ts/jobs/helpers/sendNullMessage.ts b/ts/jobs/helpers/sendNullMessage.ts index 6352fda07c..b6a3f8832f 100644 --- a/ts/jobs/helpers/sendNullMessage.ts +++ b/ts/jobs/helpers/sendNullMessage.ts @@ -87,7 +87,7 @@ export async function sendNullMessage( await handleMessageSend( messaging.sendIndividualProto({ contentHint, - identifier: conversation.getSendTarget(), + serviceId: conversation.getSendTarget(), options: sendOptions, proto, timestamp, diff --git a/ts/jobs/helpers/sendProfileKey.ts b/ts/jobs/helpers/sendProfileKey.ts index a718180db6..4f5a80d579 100644 --- a/ts/jobs/helpers/sendProfileKey.ts +++ b/ts/jobs/helpers/sendProfileKey.ts @@ -124,7 +124,7 @@ export async function sendProfileKey( }); sendPromise = messaging.sendIndividualProto({ contentHint, - identifier: conversation.getSendTarget(), + serviceId: conversation.getSendTarget(), options: sendOptions, proto, timestamp, @@ -135,8 +135,8 @@ export async function sendProfileKey( log.error('No revision provided, but conversation is GroupV2'); } - const ourUuid = window.textsecure.storage.user.getCheckedUuid(); - if (!conversation.hasMember(ourUuid)) { + const ourAci = window.textsecure.storage.user.getCheckedAci(); + if (!conversation.hasMember(ourAci)) { log.info( `We are not part of group ${conversation.idForLogging()}; refusing to send` ); diff --git a/ts/jobs/helpers/sendReaction.ts b/ts/jobs/helpers/sendReaction.ts index dad2223060..e1f9829986 100644 --- a/ts/jobs/helpers/sendReaction.ts +++ b/ts/jobs/helpers/sendReaction.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import { isNumber } from 'lodash'; +import { v4 as generateUuid } from 'uuid'; import * as Errors from '../../types/errors'; import { strictAssert } from '../../util/assert'; @@ -13,7 +14,8 @@ import type { ConversationModel } from '../../models/conversations'; import * as reactionUtil from '../../reactions/util'; import { isSent, SendStatus } from '../../messages/MessageSendState'; -import { getMessageById } from '../../messages/getMessageById'; +import { __DEPRECATED$getMessageById } from '../../messages/getMessageById'; +import { isIncoming } from '../../messages/helpers'; import { isMe, isDirectConversation, @@ -25,8 +27,8 @@ import { handleMessageSend } from '../../util/handleMessageSend'; import { ourProfileKeyService } from '../../services/ourProfileKey'; import { canReact, isStory } from '../../state/selectors/message'; import { findAndFormatContact } from '../../util/findAndFormatContact'; -import { UUID } from '../../types/UUID'; -import type { UUIDStringType } from '../../types/UUID'; +import type { AciString, ServiceIdString } from '../../types/ServiceId'; +import { isAciString } from '../../util/isAciString'; import { handleMultipleSendErrors } from './handleMultipleSendErrors'; import { incrementMessageCounter } from '../../util/incrementMessageCounter'; @@ -51,14 +53,14 @@ export async function sendReaction( data: ReactionJobData ): Promise { const { messageId, revision } = data; - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); + const ourAci = window.textsecure.storage.user.getCheckedAci(); await window.ConversationController.load(); const ourConversationId = window.ConversationController.getOurConversationIdOrThrow(); - const message = await getMessageById(messageId); + const message = await __DEPRECATED$getMessageById(messageId); if (!message) { log.info( `message ${messageId} was not found, maybe because it was deleted. Giving up on sending its reactions` @@ -84,7 +86,7 @@ export async function sendReaction( if (!canReact(message.attributes, ourConversationId, findAndFormatContact)) { log.info(`could not react to ${messageId}. Removing this pending reaction`); markReactionFailed(message, pendingReaction); - await window.Signal.Data.saveMessage(message.attributes, { ourUuid }); + await window.Signal.Data.saveMessage(message.attributes, { ourAci }); return; } @@ -93,7 +95,7 @@ export async function sendReaction( `reacting to message ${messageId} ran out of time. Giving up on sending it` ); markReactionFailed(message, pendingReaction); - await window.Signal.Data.saveMessage(message.attributes, { ourUuid }); + await window.Signal.Data.saveMessage(message.attributes, { ourAci }); return; } @@ -115,20 +117,20 @@ export async function sendReaction( const expireTimer = messageConversation.get('expireTimer'); const { - allRecipientIdentifiers, - recipientIdentifiersWithoutMe, - untrustedUuids, + allRecipientServiceIds, + recipientServiceIdsWithoutMe, + untrustedServiceIds, } = getRecipients(log, pendingReaction, conversation); - if (untrustedUuids.length) { + if (untrustedServiceIds.length) { window.reduxActions.conversations.conversationStoppedByMissingVerification( { conversationId: conversation.id, - untrustedUuids, + untrustedServiceIds, } ); throw new Error( - `Reaction for message ${messageId} sending blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.` + `Reaction for message ${messageId} sending blocked because ${untrustedServiceIds.length} conversation(s) were untrusted. Failing this attempt.` ); } @@ -136,16 +138,27 @@ export async function sendReaction( ? await ourProfileKeyService.get() : undefined; - const reactionForSend = pendingReaction.emoji - ? pendingReaction - : { - ...pendingReaction, - emoji: emojiToRemove, - remove: true, - }; + const { emoji, ...restOfPendingReaction } = pendingReaction; + let targetAuthorAci: AciString; + if (isIncoming(message.attributes)) { + strictAssert( + isAciString(message.attributes.sourceServiceId), + 'incoming message does not have sender ACI' + ); + ({ sourceServiceId: targetAuthorAci } = message.attributes); + } else { + targetAuthorAci = ourAci; + } + + const reactionForSend = { + ...restOfPendingReaction, + emoji: emoji || emojiToRemove, + targetAuthorAci, + remove: !emoji, + }; const ephemeralMessageForReactionSend = new window.Whisper.Message({ - id: UUID.generate().toString(), + id: generateUuid(), type: 'outgoing', conversationId: conversation.get('id'), sent_at: pendingReaction.timestamp, @@ -160,30 +173,36 @@ export async function sendReaction( }) ), }); + // Adds the reaction's attributes to the message cache so that we can + // safely `set` on it later. + window.MessageCache.toMessageAttributes( + ephemeralMessageForReactionSend.attributes + ); ephemeralMessageForReactionSend.doNotSave = true; let didFullySend: boolean; const successfulConversationIds = new Set(); - if (recipientIdentifiersWithoutMe.length === 0) { + if (recipientServiceIdsWithoutMe.length === 0) { log.info('sending sync reaction message only'); const dataMessage = await messaging.getDataOrEditMessage({ attachments: [], expireTimer, groupV2: conversation.getGroupV2Info({ - members: recipientIdentifiersWithoutMe, + members: recipientServiceIdsWithoutMe, }), preview: [], profileKey, reaction: reactionForSend, - recipients: allRecipientIdentifiers, + recipients: allRecipientServiceIds, timestamp: pendingReaction.timestamp, }); - await ephemeralMessageForReactionSend.sendSyncMessageOnly( + await ephemeralMessageForReactionSend.sendSyncMessageOnly({ dataMessage, - saveErrors - ); + saveErrors, + targetTimestamp: pendingReaction.timestamp, + }); didFullySend = true; successfulConversationIds.add(ourConversationId); @@ -216,8 +235,8 @@ export async function sendReaction( } log.info('sending direct reaction message'); - promise = messaging.sendMessageToIdentifier({ - identifier: recipientIdentifiersWithoutMe[0], + promise = messaging.sendMessageToServiceId({ + serviceId: recipientServiceIdsWithoutMe[0], messageText: undefined, attachments: [], quote: undefined, @@ -245,7 +264,7 @@ export async function sendReaction( } const groupV2Info = conversation.getGroupV2Info({ - members: recipientIdentifiersWithoutMe, + members: recipientServiceIdsWithoutMe, }); if (groupV2Info && isNumber(revision)) { groupV2Info.revision = revision; @@ -271,13 +290,14 @@ export async function sendReaction( ); } - await ephemeralMessageForReactionSend.send( - handleMessageSend(promise, { + await ephemeralMessageForReactionSend.send({ + promise: handleMessageSend(promise, { messageIds: [messageId], sendType: 'reaction', }), - saveErrors - ); + saveErrors, + targetTimestamp: pendingReaction.timestamp, + }); // Because message.send swallows and processes errors, we'll await the inner promise // to get the SendMessageProtoError, which gives us information upstream @@ -316,12 +336,16 @@ export async function sendReaction( shouldSave: false, }); await window.Signal.Data.saveMessage(reactionMessage.attributes, { - ourUuid, + ourAci, forceSave: true, }); void conversation.addSingleMessage( - window.MessageController.register(reactionMessage.id, reactionMessage) + window.MessageCache.__DEPRECATED$register( + reactionMessage.id, + reactionMessage, + 'sendReaction' + ) ); } } @@ -350,7 +374,7 @@ export async function sendReaction( toThrow: originalError || thrownError, }); } finally { - await window.Signal.Data.saveMessage(message.attributes, { ourUuid }); + await window.Signal.Data.saveMessage(message.attributes, { ourAci }); } } @@ -365,7 +389,7 @@ const setReactions = ( if (reactions.length) { message.set('reactions', reactions); } else { - message.unset('reactions'); + message.set('reactions', undefined); } }; @@ -374,13 +398,13 @@ function getRecipients( reaction: Readonly, conversation: ConversationModel ): { - allRecipientIdentifiers: Array; - recipientIdentifiersWithoutMe: Array; - untrustedUuids: Array; + allRecipientServiceIds: Array; + recipientServiceIdsWithoutMe: Array; + untrustedServiceIds: Array; } { - const allRecipientIdentifiers: Array = []; - const recipientIdentifiersWithoutMe: Array = []; - const untrustedUuids: Array = []; + const allRecipientServiceIds: Array = []; + const recipientServiceIdsWithoutMe: Array = []; + const untrustedServiceIds: Array = []; const currentConversationRecipients = conversation.getMemberConversationIds(); @@ -401,14 +425,14 @@ function getRecipients( } if (recipient.isUntrusted()) { - const uuid = recipient.get('uuid'); - if (!uuid) { + const serviceId = recipient.getServiceId(); + if (!serviceId) { log.error( - `sendReaction/getRecipients: Untrusted conversation ${recipient.idForLogging()} missing UUID.` + `sendReaction/getRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.` ); continue; } - untrustedUuids.push(uuid); + untrustedServiceIds.push(serviceId); continue; } if (recipient.isUnregistered()) { @@ -418,16 +442,16 @@ function getRecipients( continue; } - allRecipientIdentifiers.push(recipientIdentifier); + allRecipientServiceIds.push(recipientIdentifier); if (!isRecipientMe) { - recipientIdentifiersWithoutMe.push(recipientIdentifier); + recipientServiceIdsWithoutMe.push(recipientIdentifier); } } return { - allRecipientIdentifiers, - recipientIdentifiersWithoutMe, - untrustedUuids, + allRecipientServiceIds, + recipientServiceIdsWithoutMe, + untrustedServiceIds, }; } diff --git a/ts/jobs/helpers/sendResendRequest.ts b/ts/jobs/helpers/sendResendRequest.ts index 81a4ff047e..05c815d6bc 100644 --- a/ts/jobs/helpers/sendResendRequest.ts +++ b/ts/jobs/helpers/sendResendRequest.ts @@ -32,7 +32,7 @@ function failoverToLocalReset( logger: LoggerType, options: Pick< DecryptionErrorEventData, - 'senderUuid' | 'senderDevice' | 'timestamp' + 'senderAci' | 'senderDevice' | 'timestamp' > ) { logger.error('Failing over to local reset'); @@ -48,8 +48,13 @@ export async function sendResendRequest( timeRemaining, log, }: ConversationQueueJobBundle, - data: ResendRequestJobData + { senderAci, ...restOfData }: ResendRequestJobData ): Promise { + const data = { + ...restOfData, + senderAci, + }; + const { contentHint, groupId, @@ -83,9 +88,8 @@ export async function sendResendRequest( // Note: we will send to blocked users, to those still in message request state, etc. // Any needed blocking should still apply once the decryption error is fixed. - const senderUuid = conversation.get('uuid'); - if (!senderUuid) { - log.error('conversation was missing a uuid, cancelling job.'); + if (conversation.getAci() !== senderAci) { + log.error('conversation was missing a aci, cancelling job.'); failoverToLocalReset(log, data); return; } @@ -106,7 +110,7 @@ export async function sendResendRequest( await handleMessageSend( messaging.sendMessageProtoAndWait({ timestamp, - recipients: [senderUuid], + recipients: [senderAci], proto: plaintext, contentHint: ContentHint.DEFAULT, groupId, @@ -134,7 +138,7 @@ export async function sendResendRequest( receivedAt: receivedAtDate, receivedAtCounter, sentAt: timestamp, - senderUuid, + senderAci, wasOpened, }); @@ -155,7 +159,7 @@ export async function sendResendRequest( await conversation.addDeliveryIssue({ receivedAt: receivedAtDate, receivedAtCounter, - senderUuid, + senderAci, sentAt: timestamp, }); }) diff --git a/ts/jobs/helpers/sendSavedProto.ts b/ts/jobs/helpers/sendSavedProto.ts index 8b7d9212af..13ae726751 100644 --- a/ts/jobs/helpers/sendSavedProto.ts +++ b/ts/jobs/helpers/sendSavedProto.ts @@ -57,10 +57,10 @@ export async function sendSavedProto( return; } - const uuid = conversation.get('uuid'); - if (!uuid) { + const serviceId = conversation.getServiceId(); + if (!serviceId) { log.info( - `conversation ${conversation.idForLogging()} was missing uuid, cancelling job.` + `conversation ${conversation.idForLogging()} was missing serviceId, cancelling job.` ); return; } @@ -84,7 +84,7 @@ export async function sendSavedProto( groupId, options: sendOptions, proto, - recipients: [uuid], + recipients: [serviceId], timestamp: originalTimestamp, urgent, story, diff --git a/ts/jobs/helpers/sendSenderKeyDistribution.ts b/ts/jobs/helpers/sendSenderKeyDistribution.ts index 6076dabc99..5aecdcfd99 100644 --- a/ts/jobs/helpers/sendSenderKeyDistribution.ts +++ b/ts/jobs/helpers/sendSenderKeyDistribution.ts @@ -48,7 +48,9 @@ export async function sendSenderKeyDistribution( ); if (!isDirectConversation(conversation.attributes)) { - log.info('Failing attempt to send null message to group'); + log.info( + 'Failing attempt to send sender key distribution message to group' + ); return; } @@ -67,7 +69,7 @@ export async function sendSenderKeyDistribution( const { groupId } = data; const group = window.ConversationController.get(groupId); const distributionId = group?.get('senderKeyInfo')?.distributionId; - const uuid = conversation.get('uuid'); + const serviceId = conversation.getServiceId(); if (!distributionId) { log.info( @@ -76,9 +78,9 @@ export async function sendSenderKeyDistribution( return; } - if (!uuid) { + if (!serviceId) { log.info( - `conversation ${conversation.idForLogging()} was missing uuid, cancelling job.` + `conversation ${conversation.idForLogging()} was missing serviceId, cancelling job.` ); return; } @@ -89,7 +91,7 @@ export async function sendSenderKeyDistribution( { distributionId, groupId, - identifiers: [uuid], + serviceIds: [serviceId], throwIfNotInDatabase: true, urgent: false, }, diff --git a/ts/jobs/helpers/sendStory.ts b/ts/jobs/helpers/sendStory.ts index bca8c998d2..466fa190b0 100644 --- a/ts/jobs/helpers/sendStory.ts +++ b/ts/jobs/helpers/sendStory.ts @@ -19,7 +19,8 @@ import { SendActionType, sendStateReducer, } from '../../messages/MessageSendState'; -import type { UUIDStringType } from '../../types/UUID'; +import type { ServiceIdString } from '../../types/ServiceId'; +import type { StoryDistributionIdString } from '../../types/StoryDistributionId'; import * as Errors from '../../types/errors'; import type { StoryMessageRecipientsType } from '../../types/Stories'; import dataInterface from '../../sql/Client'; @@ -34,7 +35,6 @@ import { handleMultipleSendErrors } from './handleMultipleSendErrors'; import { isGroupV2, isMe } from '../../util/whatTypeOfConversation'; import { ourProfileKeyService } from '../../services/ourProfileKey'; import { sendContentMessageToGroup } from '../../util/sendToGroup'; -import { getTaggedConversationUuid } from '../../util/getConversationUuid'; import { distributionListToSendTarget } from '../../util/distributionListToSendTarget'; import { uploadAttachment } from '../../util/uploadAttachment'; import { SendMessageChallengeError } from '../../textsecure/Errors'; @@ -190,33 +190,41 @@ export async function sendStory( }); } - const canReplyUuids = new Set(); - const recipientsByUuid = new Map>(); + const canReplyServiceIds = new Set(); + const recipientsByServiceId = new Map< + ServiceIdString, + Set + >(); const sentConversationIds = new Map(); - const sentUuids = new Set(); + const sentServiceIds = new Set(); // This function is used to keep track of all the recipients so once we're // done with our send we can build up the storyMessageRecipients object for // sending in the sync message. - function addDistributionListToUuidSent( - listId: string | undefined, - uuid: string, + function addDistributionListToServiceIdSent( + listId: StoryDistributionIdString | undefined, + serviceId: ServiceIdString, canReply?: boolean ): void { - if (conversation.get('uuid') === uuid) { + if (conversation.getServiceId() === serviceId) { return; } - const distributionListIds = recipientsByUuid.get(uuid) || new Set(); + const distributionListIds = + recipientsByServiceId.get(serviceId) || + new Set(); if (listId) { - recipientsByUuid.set(uuid, new Set([...distributionListIds, listId])); + recipientsByServiceId.set( + serviceId, + new Set([...distributionListIds, listId]) + ); } else { - recipientsByUuid.set(uuid, distributionListIds); + recipientsByServiceId.set(serviceId, distributionListIds); } if (canReply) { - canReplyUuids.add(uuid); + canReplyServiceIds.add(serviceId); } } @@ -273,36 +281,36 @@ export async function sendStory( let originalError: Error | undefined; const { - allRecipientIds, - allowedReplyByUuid, - pendingSendRecipientIds, + allRecipientServiceIds, + allowedReplyByServiceId, + pendingSendRecipientServiceIds, sentRecipientIds, - untrustedUuids, + untrustedServiceIds, } = getMessageRecipients({ log, message, }); try { - if (untrustedUuids.length) { + if (untrustedServiceIds.length) { window.reduxActions.conversations.conversationStoppedByMissingVerification( { conversationId: conversation.id, distributionId, - untrustedUuids, + untrustedServiceIds, } ); throw new Error( - `${logId}: sending blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.` + `${logId}: sending blocked because ${untrustedServiceIds.length} conversation(s) were untrusted. Failing this attempt.` ); } - if (!pendingSendRecipientIds.length) { - allRecipientIds.forEach(uuid => - addDistributionListToUuidSent( + if (!pendingSendRecipientServiceIds.length) { + allRecipientServiceIds.forEach(serviceId => + addDistributionListToServiceIdSent( listId, - uuid, - allowedReplyByUuid.get(uuid) + serviceId, + allowedReplyByServiceId.get(serviceId) ) ); return; @@ -311,7 +319,7 @@ export async function sendStory( const { ContentHint } = Proto.UnidentifiedSenderMessage.Message; const sendOptions = await getSendOptionsForRecipients( - pendingSendRecipientIds, + pendingSendRecipientServiceIds, { story: true } ); @@ -332,7 +340,7 @@ export async function sendStory( const sendTarget = distributionList ? distributionListToSendTarget( distributionList, - pendingSendRecipientIds + pendingSendRecipientServiceIds ) : conversation.toSenderKeyTarget(); @@ -344,7 +352,7 @@ export async function sendStory( contentMessage, isPartialSend: false, messageId: undefined, - recipients: pendingSendRecipientIds, + recipients: pendingSendRecipientServiceIds, sendOptions, sendTarget, sendType: 'story', @@ -357,13 +365,14 @@ export async function sendStory( // eslint-disable-next-line no-param-reassign message.doNotSendSyncMessage = true; - const messageSendPromise = message.send( - handleMessageSend(innerPromise, { + const messageSendPromise = message.send({ + promise: handleMessageSend(innerPromise, { messageIds: [message.id], sendType: 'story', }), - saveErrors - ); + saveErrors, + targetTimestamp: message.get('timestamp'), + }); // Because message.send swallows and processes errors, we'll await the // inner promise to get the SendMessageProtoError, which gives us @@ -399,19 +408,19 @@ export async function sendStory( const recipient = window.ConversationController.get( recipientConversationId ); - const uuid = recipient?.get('uuid'); - if (!uuid) { + const serviceId = recipient?.getServiceId(); + if (!serviceId) { return; } - sentUuids.add(uuid); + sentServiceIds.add(serviceId); } ); - allRecipientIds.forEach(uuid => { - addDistributionListToUuidSent( + allRecipientServiceIds.forEach(serviceId => { + addDistributionListToServiceIdSent( listId, - uuid, - allowedReplyByUuid.get(uuid) + serviceId, + allowedReplyByServiceId.get(serviceId) ); }); @@ -436,6 +445,7 @@ export async function sendStory( reason: 'conversationJobQueue.run(' + `${conversation.idForLogging()}, story, ${timestamp}/${distributionId})`, + silent: false, }, error.data ); @@ -532,36 +542,27 @@ export async function sendStory( message.set('sendStateByConversationId', newSendStateByConversationId); return window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); }) ); // Remove any unsent recipients - recipientsByUuid.forEach((_value, uuid) => { - if (sentUuids.has(uuid)) { + recipientsByServiceId.forEach((_value, serviceId) => { + if (sentServiceIds.has(serviceId)) { return; } - recipientsByUuid.delete(uuid); + recipientsByServiceId.delete(serviceId); }); // Build up the sync message's storyMessageRecipients and send it const storyMessageRecipients: StoryMessageRecipientsType = []; - recipientsByUuid.forEach((distributionListIds, destinationUuid) => { - const recipient = window.ConversationController.get(destinationUuid); - if (!recipient) { - return; - } - const taggedUuid = getTaggedConversationUuid(recipient.attributes); - if (!taggedUuid) { - return; - } + recipientsByServiceId.forEach((distributionListIds, destinationServiceId) => { storyMessageRecipients.push({ - destinationAci: taggedUuid.aci, - destinationPni: taggedUuid.pni, + destinationServiceId, distributionListIds: Array.from(distributionListIds), - isAllowedToReply: canReplyUuids.has(destinationUuid), + isAllowedToReply: canReplyServiceIds.has(destinationServiceId), }); }); @@ -577,7 +578,7 @@ export async function sendStory( await messaging.sendSyncMessage({ // Note: these two fields will be undefined if we're sending to a group destination: conversation.get('e164'), - destinationUuid: getTaggedConversationUuid(conversation.attributes), + destinationServiceId: conversation.getServiceId(), storyMessage: originalStoryMessage, storyMessageRecipients, expirationStartTimestamp: null, @@ -607,17 +608,17 @@ function getMessageRecipients({ log: LoggerType; message: MessageModel; }>): { - allRecipientIds: Array; - allowedReplyByUuid: Map; - pendingSendRecipientIds: Array; + allRecipientServiceIds: Array; + allowedReplyByServiceId: Map; + pendingSendRecipientServiceIds: Array; sentRecipientIds: Array; - untrustedUuids: Array; + untrustedServiceIds: Array; } { - const allRecipientIds: Array = []; - const allowedReplyByUuid = new Map(); - const pendingSendRecipientIds: Array = []; + const allRecipientServiceIds: Array = []; + const allowedReplyByServiceId = new Map(); + const pendingSendRecipientServiceIds: Array = []; const sentRecipientIds: Array = []; - const untrustedUuids: Array = []; + const untrustedServiceIds: Array = []; Object.entries(message.get('sendStateByConversationId') || {}).forEach( ([recipientConversationId, sendState]) => { @@ -634,14 +635,14 @@ function getMessageRecipients({ } if (recipient.isUntrusted()) { - const uuid = recipient.get('uuid'); - if (!uuid) { + const serviceId = recipient.getServiceId(); + if (!serviceId) { log.error( - `stories.sendStory/getMessageRecipients: Untrusted conversation ${recipient.idForLogging()} missing UUID.` + `stories.sendStory/getMessageRecipients: Untrusted conversation ${recipient.idForLogging()} missing serviceId.` ); return; } - untrustedUuids.push(uuid); + untrustedServiceIds.push(serviceId); return; } if (recipient.isUnregistered()) { @@ -653,11 +654,11 @@ function getMessageRecipients({ return; } - allowedReplyByUuid.set( + allowedReplyByServiceId.set( recipientSendTarget, Boolean(sendState.isAllowedToReplyToStory) ); - allRecipientIds.push(recipientSendTarget); + allRecipientServiceIds.push(recipientSendTarget); if (sendState.isAlreadyIncludedInAnotherDistributionList) { return; @@ -668,16 +669,16 @@ function getMessageRecipients({ return; } - pendingSendRecipientIds.push(recipientSendTarget); + pendingSendRecipientServiceIds.push(recipientSendTarget); } ); return { - allRecipientIds, - allowedReplyByUuid, - pendingSendRecipientIds, + allRecipientServiceIds, + allowedReplyByServiceId, + pendingSendRecipientServiceIds, sentRecipientIds, - untrustedUuids, + untrustedServiceIds, }; } @@ -688,7 +689,7 @@ async function markMessageFailed( message.markFailed(); void message.saveErrors(errors, { skipSave: true }); await window.Signal.Data.saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } diff --git a/ts/jobs/helpers/shouldSendToConversation.ts b/ts/jobs/helpers/shouldSendToConversation.ts index 283721af3d..dbe0d126af 100644 --- a/ts/jobs/helpers/shouldSendToConversation.ts +++ b/ts/jobs/helpers/shouldSendToConversation.ts @@ -5,16 +5,16 @@ import type { ConversationModel } from '../../models/conversations'; import type { LoggerType } from '../../types/Logging'; import { getRecipients } from '../../util/getRecipients'; import { isConversationAccepted } from '../../util/isConversationAccepted'; -import { getUntrustedConversationUuids } from './getUntrustedConversationUuids'; +import { getUntrustedConversationServiceIds } from './getUntrustedConversationServiceIds'; export function shouldSendToConversation( conversation: ConversationModel, log: LoggerType ): boolean { const recipients = getRecipients(conversation.attributes); - const untrustedUuids = getUntrustedConversationUuids(recipients); + const untrustedServiceIds = getUntrustedConversationServiceIds(recipients); - if (untrustedUuids.length) { + if (untrustedServiceIds.length) { log.info( `conversation ${conversation.idForLogging()} has untrusted recipients; refusing to send` ); diff --git a/ts/jobs/helpers/syncHelpers.ts b/ts/jobs/helpers/syncHelpers.ts index 5cdae7f178..d2ad61ec71 100644 --- a/ts/jobs/helpers/syncHelpers.ts +++ b/ts/jobs/helpers/syncHelpers.ts @@ -3,6 +3,8 @@ import { chunk } from 'lodash'; import type { LoggerType } from '../../types/Logging'; +import type { AciString } from '../../types/ServiceId'; +import { normalizeAci } from '../../util/normalizeAci'; import { getSendOptions } from '../../util/getSendOptions'; import type { SendTypesType } from '../../util/handleMessageSend'; import { handleMessageSend } from '../../util/handleMessageSend'; @@ -20,7 +22,7 @@ const CHUNK_SIZE = 100; export type SyncType = { messageId?: string; senderE164?: string; - senderUuid?: string; + senderAci?: AciString; timestamp: number; }; export enum SyncTypeList { @@ -40,13 +42,18 @@ export function parseRawSyncDataArray(value: unknown): Array { return value.map((item: unknown) => { strictAssert(isRecord(item), 'sync is not an object'); - const { messageId, senderE164, senderUuid, timestamp } = item; + const { messageId, senderE164, timestamp } = item; strictAssert(typeof timestamp === 'number', 'timestamp should be a number'); + const rawSenderAci = parseOptionalString('senderAci', item.senderAci); + const senderAci = rawSenderAci + ? normalizeAci(rawSenderAci, 'parseRawSyncDataArray') + : undefined; + return { messageId: parseOptionalString('messageId', messageId), senderE164: parseOptionalString('senderE164', senderE164), - senderUuid: parseOptionalString('senderUuid', senderUuid), + senderAci, timestamp, }; }); @@ -147,9 +154,18 @@ export async function runSyncJob({ } } + const aciSyncs = syncs.map(({ senderAci, ...rest }) => { + return { + ...rest, + senderAci: senderAci + ? normalizeAci(senderAci, 'syncHelpers.senderAci') + : undefined, + }; + }); + try { await Promise.all( - chunk(syncs, CHUNK_SIZE).map(batch => { + chunk(aciSyncs, CHUNK_SIZE).map(batch => { const messageIds = batch.map(item => item.messageId).filter(isNotNil); return handleMessageSend(doSync(batch, sendOptions), { diff --git a/ts/jobs/readSyncJobQueue.ts b/ts/jobs/readSyncJobQueue.ts index 58bc34be13..ef6f347036 100644 --- a/ts/jobs/readSyncJobQueue.ts +++ b/ts/jobs/readSyncJobQueue.ts @@ -13,6 +13,7 @@ import { import { strictAssert } from '../util/assert'; import { isRecord } from '../util/isRecord'; +import type { JOB_STATUS } from './JobQueue'; import { JobQueue } from './JobQueue'; import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; @@ -31,7 +32,7 @@ export class ReadSyncJobQueue extends JobQueue { protected async run( { data, timestamp }: Readonly<{ data: ReadSyncJobData; timestamp: number }>, { attempt, log }: Readonly<{ attempt: number; log: LoggerType }> - ): Promise { + ): Promise { await runSyncJob({ attempt, log, @@ -40,6 +41,8 @@ export class ReadSyncJobQueue extends JobQueue { timestamp, type: SyncTypeList.Read, }); + + return undefined; } } diff --git a/ts/jobs/removeStorageKeyJobQueue.ts b/ts/jobs/removeStorageKeyJobQueue.ts index 8b3e86fc32..c911ef6a34 100644 --- a/ts/jobs/removeStorageKeyJobQueue.ts +++ b/ts/jobs/removeStorageKeyJobQueue.ts @@ -3,7 +3,9 @@ import { z } from 'zod'; +import type { JOB_STATUS } from './JobQueue'; import { JobQueue } from './JobQueue'; + import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; const removeStorageKeyJobDataSchema = z.object({ @@ -24,12 +26,16 @@ export class RemoveStorageKeyJobQueue extends JobQueue protected async run({ data, - }: Readonly<{ data: RemoveStorageKeyJobData }>): Promise { + }: Readonly<{ data: RemoveStorageKeyJobData }>): Promise< + typeof JOB_STATUS.NEEDS_RETRY | undefined + > { await new Promise(resolve => { window.storage.onready(resolve); }); await window.storage.remove(data.key); + + return undefined; } } diff --git a/ts/jobs/reportSpamJobQueue.ts b/ts/jobs/reportSpamJobQueue.ts index 9ea4e22df9..6ab92b41a1 100644 --- a/ts/jobs/reportSpamJobQueue.ts +++ b/ts/jobs/reportSpamJobQueue.ts @@ -7,8 +7,10 @@ import { strictAssert } from '../util/assert'; import { waitForOnline } from '../util/waitForOnline'; import { isDone as isDeviceLinked } from '../util/registration'; import type { LoggerType } from '../types/Logging'; +import { aciSchema } from '../types/ServiceId'; import { map } from '../util/iterables'; +import type { JOB_STATUS } from './JobQueue'; import { JobQueue } from './JobQueue'; import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; import { parseIntWithFallback } from '../util/parseIntWithFallback'; @@ -27,7 +29,7 @@ const isRetriable4xxStatus = (code: number): boolean => RETRYABLE_4XX_FAILURE_STATUSES.has(code); const reportSpamJobDataSchema = z.object({ - uuid: z.string().min(1), + aci: aciSchema, token: z.string().optional(), serverGuids: z.string().array().min(1).max(1000), }); @@ -48,8 +50,8 @@ export class ReportSpamJobQueue extends JobQueue { protected async run( { data }: Readonly<{ data: ReportSpamJobData }>, { log }: Readonly<{ log: LoggerType }> - ): Promise { - const { uuid: senderUuid, token, serverGuids } = data; + ): Promise { + const { aci: senderAci, token, serverGuids } = data; await new Promise(resolve => { window.storage.onready(resolve); @@ -57,7 +59,7 @@ export class ReportSpamJobQueue extends JobQueue { if (!isDeviceLinked()) { log.info("reportSpamJobQueue: skipping this job because we're unlinked"); - return; + return undefined; } await waitForOnline(window.navigator, window); @@ -68,9 +70,11 @@ export class ReportSpamJobQueue extends JobQueue { try { await Promise.all( map(serverGuids, serverGuid => - server.reportMessage({ senderUuid, serverGuid, token }) + server.reportMessage({ senderAci, serverGuid, token }) ) ); + + return undefined; } catch (err: unknown) { if (!(err instanceof HTTPError)) { throw err; @@ -87,7 +91,7 @@ export class ReportSpamJobQueue extends JobQueue { log.info( 'reportSpamJobQueue: server responded with 508. Giving up on this job' ); - return; + return undefined; } if (isRetriable4xxStatus(code) || is5xxStatus(code)) { @@ -105,7 +109,7 @@ export class ReportSpamJobQueue extends JobQueue { log.error( `reportSpamJobQueue: server responded with ${code} status code. Giving up on this job` ); - return; + return undefined; } throw err; diff --git a/ts/jobs/singleProtoJobQueue.ts b/ts/jobs/singleProtoJobQueue.ts index 98c9282ed9..4208650e18 100644 --- a/ts/jobs/singleProtoJobQueue.ts +++ b/ts/jobs/singleProtoJobQueue.ts @@ -8,6 +8,7 @@ import * as Bytes from '../Bytes'; import type { LoggerType } from '../types/Logging'; import { exponentialBackoffMaxAttempts } from '../util/exponentialBackoff'; import type { ParsedJob } from './types'; +import type { JOB_STATUS } from './JobQueue'; import { JobQueue } from './JobQueue'; import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; import { DAY } from '../util/durations'; @@ -51,7 +52,7 @@ export class SingleProtoJobQueue extends JobQueue { timestamp, }: Readonly<{ data: SingleProtoJobData; timestamp: number }>, { attempt, log }: Readonly<{ attempt: number; log: LoggerType }> - ): Promise { + ): Promise { const timeRemaining = timestamp + MAX_RETRY_TIME - Date.now(); const isFinalAttempt = attempt >= MAX_ATTEMPTS; @@ -62,12 +63,12 @@ export class SingleProtoJobQueue extends JobQueue { skipWait: false, }); if (!shouldContinue) { - return; + return undefined; } const { contentHint, - identifier, + serviceId, isSyncMessage, messageIds = [], protoBase64, @@ -75,33 +76,31 @@ export class SingleProtoJobQueue extends JobQueue { urgent, } = data; log.info( - `starting ${type} send to ${identifier} with timestamp ${timestamp}` + `starting ${type} send to ${serviceId} with timestamp ${timestamp}` ); - const conversation = window.ConversationController.get(identifier); + const conversation = window.ConversationController.get(serviceId); if (!conversation) { - throw new Error( - `Failed to get conversation for identifier ${identifier}` - ); + throw new Error(`Failed to get conversation for serviceId ${serviceId}`); } if (!isConversationAccepted(conversation.attributes)) { log.info( `conversation ${conversation.idForLogging()} is not accepted; refusing to send` ); - return; + return undefined; } if (isConversationUnregistered(conversation.attributes)) { log.info( `conversation ${conversation.idForLogging()} is unregistered; refusing to send` ); - return; + return undefined; } if (conversation.isBlocked()) { log.info( `conversation ${conversation.idForLogging()} is blocked; refusing to send` ); - return; + return undefined; } const proto = Proto.Content.decode(Bytes.fromBase64(protoBase64)); @@ -118,7 +117,7 @@ export class SingleProtoJobQueue extends JobQueue { await handleMessageSend( messaging.sendIndividualProto({ contentHint, - identifier, + serviceId, options, proto, timestamp, @@ -135,6 +134,8 @@ export class SingleProtoJobQueue extends JobQueue { toThrow: error, }); } + + return undefined; } } diff --git a/ts/jobs/viewOnceOpenJobQueue.ts b/ts/jobs/viewOnceOpenJobQueue.ts index d90a5862c2..7eb1653acc 100644 --- a/ts/jobs/viewOnceOpenJobQueue.ts +++ b/ts/jobs/viewOnceOpenJobQueue.ts @@ -13,6 +13,7 @@ import { import { strictAssert } from '../util/assert'; import { isRecord } from '../util/isRecord'; +import type { JOB_STATUS } from './JobQueue'; import { JobQueue } from './JobQueue'; import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; @@ -34,7 +35,7 @@ export class ViewOnceOpenJobQueue extends JobQueue { timestamp, }: Readonly<{ data: ViewOnceOpenJobData; timestamp: number }>, { attempt, log }: Readonly<{ attempt: number; log: LoggerType }> - ): Promise { + ): Promise { await runSyncJob({ attempt, log, @@ -43,6 +44,8 @@ export class ViewOnceOpenJobQueue extends JobQueue { timestamp, type: SyncTypeList.ViewOnceOpen, }); + + return undefined; } } diff --git a/ts/jobs/viewSyncJobQueue.ts b/ts/jobs/viewSyncJobQueue.ts index 26ec9cdcf0..840607d5f8 100644 --- a/ts/jobs/viewSyncJobQueue.ts +++ b/ts/jobs/viewSyncJobQueue.ts @@ -13,6 +13,7 @@ import { import { strictAssert } from '../util/assert'; import { isRecord } from '../util/isRecord'; +import type { JOB_STATUS } from './JobQueue'; import { JobQueue } from './JobQueue'; import { jobQueueDatabaseStore } from './JobQueueDatabaseStore'; @@ -31,7 +32,7 @@ export class ViewSyncJobQueue extends JobQueue { protected async run( { data, timestamp }: Readonly<{ data: ViewSyncJobData; timestamp: number }>, { attempt, log }: Readonly<{ attempt: number; log: LoggerType }> - ): Promise { + ): Promise { await runSyncJob({ attempt, log, @@ -40,6 +41,8 @@ export class ViewSyncJobQueue extends JobQueue { timestamp, type: SyncTypeList.View, }); + + return undefined; } } diff --git a/ts/linkPreviews/linkPreviewFetch.ts b/ts/linkPreviews/linkPreviewFetch.ts index 8da77fcf8d..1423c551a7 100644 --- a/ts/linkPreviews/linkPreviewFetch.ts +++ b/ts/linkPreviews/linkPreviewFetch.ts @@ -612,6 +612,7 @@ export async function fetchLinkPreviewImage( const { blob: xcodedDataBlob } = await scaleImageToLevel( dataBlob, contentType, + dataBlob.size, false ); const xcodedDataArrayBuffer = await blobToArrayBuffer(xcodedDataBlob); diff --git a/ts/logging/debuglogs.ts b/ts/logging/debuglogs.ts index cb53c14819..8fc662df6f 100644 --- a/ts/logging/debuglogs.ts +++ b/ts/logging/debuglogs.ts @@ -42,7 +42,8 @@ const getHeader = ( nodeVersion: string, appVersion: string, osVersion: string, - userAgent: string + userAgent: string, + linuxVersion?: string ): string => [ headerSection('System info', { @@ -52,6 +53,7 @@ const getHeader = ( Environment: getEnvironment(), 'App version': appVersion, 'OS version': osVersion, + ...(linuxVersion && { 'Linux version': linuxVersion }), }), headerSection('User info', user), headerSection('Capabilities', capabilities), @@ -84,13 +86,21 @@ export function getLog( nodeVersion: string, appVersion: string, osVersion: string, - userAgent: string + userAgent: string, + linuxVersion?: string ): string { let header: string; let body: string; if (isFetchLogIpcData(data)) { const { logEntries } = data; - header = getHeader(data, nodeVersion, appVersion, osVersion, userAgent); + header = getHeader( + data, + nodeVersion, + appVersion, + osVersion, + userAgent, + linuxVersion + ); body = logEntries.map(formatLine).join('\n'); } else { header = headerSectionTitle('Partial logs'); diff --git a/ts/main/settingsChannel.ts b/ts/main/settingsChannel.ts index c2212b15e1..4280f2af67 100644 --- a/ts/main/settingsChannel.ts +++ b/ts/main/settingsChannel.ts @@ -19,6 +19,7 @@ const EPHEMERAL_NAME_MAP = new Map([ ['spellCheck', 'spell-check'], ['systemTraySetting', 'system-tray-setting'], ['themeSetting', 'theme-setting'], + ['localeOverride', 'localeOverride'], ]); type ResponseQueueEntry = Readonly<{ @@ -79,6 +80,9 @@ export class SettingsChannel extends EventEmitter { isEphemeral: true, }); + this.installSetting('localeOverride', { + isEphemeral: true, + }); this.installSetting('notificationSetting'); this.installSetting('notificationDrawAttention'); this.installSetting('audioMessage'); diff --git a/ts/mediaEditor/MediaEditorFabricCropRect.ts b/ts/mediaEditor/MediaEditorFabricCropRect.ts index bb180cc860..5ab255e049 100644 --- a/ts/mediaEditor/MediaEditorFabricCropRect.ts +++ b/ts/mediaEditor/MediaEditorFabricCropRect.ts @@ -29,26 +29,19 @@ export class MediaEditorFabricCropRect extends fabric.Rect { const canvasHeight = this.canvas.getHeight(); const canvasWidth = this.canvas.getWidth(); - if (height > canvasHeight || width > canvasWidth) { - this.canvas.discardActiveObject(); - } else { - this.set( - 'left', - clamp( - left / zoom, - MediaEditorFabricCropRect.PADDING / zoom, - (canvasWidth - width - MediaEditorFabricCropRect.PADDING) / zoom - ) - ); - this.set( - 'top', - clamp( - top / zoom, - MediaEditorFabricCropRect.PADDING / zoom, - (canvasHeight - height - MediaEditorFabricCropRect.PADDING) / zoom - ) - ); - } + const nextLeft = clamp( + left / zoom, + MediaEditorFabricCropRect.PADDING / zoom, + (canvasWidth - width - MediaEditorFabricCropRect.PADDING) / zoom + ); + const nextTop = clamp( + top / zoom, + MediaEditorFabricCropRect.PADDING / zoom, + (canvasHeight - height - MediaEditorFabricCropRect.PADDING) / zoom + ); + + this.set('left', nextLeft); + this.set('top', nextTop); this.setCoords(); } diff --git a/ts/messageModifiers/AttachmentDownloads.ts b/ts/messageModifiers/AttachmentDownloads.ts index 1224c95893..22ea453b0f 100644 --- a/ts/messageModifiers/AttachmentDownloads.ts +++ b/ts/messageModifiers/AttachmentDownloads.ts @@ -15,12 +15,21 @@ import type { AttachmentDownloadJobTypeType, } from '../sql/Interface'; +import { getValue } from '../RemoteConfig'; import type { MessageModel } from '../models/messages'; import type { AttachmentType } from '../types/Attachment'; -import { getAttachmentSignature, isDownloaded } from '../types/Attachment'; +import { + AttachmentSizeError, + getAttachmentSignature, + isDownloaded, +} from '../types/Attachment'; import * as Errors from '../types/errors'; import type { LoggerType } from '../types/Logging'; import * as log from '../logging/log'; +import { + KIBIBYTE, + getMaximumIncomingAttachmentSizeInKb, +} from '../types/AttachmentSize'; const { getMessageById, @@ -269,13 +278,40 @@ async function _runJob(job?: AttachmentDownloadJobType): Promise { return; } - await _addAttachmentToMessage( - message, - { ...attachment, pending: true }, - { type, index } - ); + let downloaded: AttachmentType | null = null; - const downloaded = await downloadAttachment(attachment); + try { + const { size } = attachment; + const maxInKib = getMaximumIncomingAttachmentSizeInKb(getValue); + const sizeInKib = size / KIBIBYTE; + if (!size || sizeInKib > maxInKib) { + throw new AttachmentSizeError( + `Attachment Job ${id}: Attachment was ${sizeInKib}kib, max is ${maxInKib}kib` + ); + } + + await _addAttachmentToMessage( + message, + { ...attachment, pending: true }, + { type, index } + ); + + // If the download is bigger than expected, we'll stop in the middle + downloaded = await downloadAttachment(attachment); + } catch (error) { + if (error instanceof AttachmentSizeError) { + log.error(Errors.toLogFormat(error)); + await _addAttachmentToMessage( + message, + _markAttachmentAsTooBig(attachment), + { type, index } + ); + await _finishJob(message, id); + return; + } + + throw error; + } if (!downloaded) { logger.warn( @@ -347,7 +383,7 @@ async function _runJob(job?: AttachmentDownloadJobType): Promise { ); if (message) { await saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } @@ -391,7 +427,7 @@ async function _getMessageById( id: string, messageId: string ): Promise { - const message = window.MessageController.getById(messageId); + const message = window.MessageCache.__DEPRECATED$getById(messageId); if (message) { return message; @@ -408,7 +444,11 @@ async function _getMessageById( } strictAssert(messageId === messageAttributes.id, 'message id mismatch'); - return window.MessageController.register(messageId, messageAttributes); + return window.MessageCache.__DEPRECATED$register( + messageId, + messageAttributes, + 'AttachmentDownloads._getMessageById' + ); } async function _finishJob( @@ -418,7 +458,7 @@ async function _finishJob( if (message) { logger.info(`attachment_downloads/_finishJob for job id: ${id}`); await saveMessage(message.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } @@ -440,6 +480,14 @@ function _markAttachmentAsPermanentError( }; } +function _markAttachmentAsTooBig(attachment: AttachmentType): AttachmentType { + return { + ...omit(attachment, ['key', 'id']), + error: true, + wasTooBig: true, + }; +} + function _markAttachmentAsTransientError( attachment: AttachmentType ): AttachmentType { diff --git a/ts/messageModifiers/Deletes.ts b/ts/messageModifiers/Deletes.ts index e01672f35a..f14a3c8e40 100644 --- a/ts/messageModifiers/Deletes.ts +++ b/ts/messageModifiers/Deletes.ts @@ -7,7 +7,6 @@ import * as log from '../logging/log'; import * as Errors from '../types/errors'; import { deleteForEveryone } from '../util/deleteForEveryone'; import { drop } from '../util/drop'; -import { filter, size } from '../util/iterables'; import { getMessageSentTimestampSet } from '../util/getMessageSentTimestampSet'; export type DeleteAttributesType = { @@ -20,28 +19,33 @@ export type DeleteAttributesType = { const deletes = new Map(); +function remove(del: DeleteAttributesType): void { + del.removeFromMessageReceiverCache(); + deletes.delete(del.envelopeId); +} + export function forMessage( messageAttributes: MessageAttributesType ): Array { const sentTimestamps = getMessageSentTimestampSet(messageAttributes); - const matchingDeletes = filter(deletes, ([_envelopeId, item]) => { + const deleteValues = Array.from(deletes.values()); + + const matchingDeletes = deleteValues.filter(item => { return ( item.fromId === getContactId(messageAttributes) && sentTimestamps.has(item.targetSentTimestamp) ); }); - if (size(matchingDeletes) > 0) { - log.info('Found early DOE for message'); - const result = Array.from(matchingDeletes); - result.forEach(([envelopeId, del]) => { - del.removeFromMessageReceiverCache(); - deletes.delete(envelopeId); - }); - return result.map(([_envelopeId, item]) => item); + if (!matchingDeletes.length) { + return []; } - return []; + log.info('Found early DOE for message'); + matchingDeletes.forEach(del => { + remove(del); + }); + return matchingDeletes; } export async function onDelete(del: DeleteAttributesType): Promise { @@ -81,18 +85,19 @@ export async function onDelete(del: DeleteAttributesType): Promise { return; } - const message = window.MessageController.register( + const message = window.MessageCache.__DEPRECATED$register( targetMessage.id, - targetMessage + targetMessage, + 'Deletes.onDelete' ); await deleteForEveryone(message, del); - deletes.delete(del.envelopeId); - del.removeFromMessageReceiverCache(); + remove(del); }) ); } catch (error) { + remove(del); log.error(`${logId}: error`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/Edits.ts b/ts/messageModifiers/Edits.ts index f088728230..e123078a89 100644 --- a/ts/messageModifiers/Edits.ts +++ b/ts/messageModifiers/Edits.ts @@ -5,10 +5,13 @@ import type { MessageAttributesType } from '../model-types.d'; import * as Errors from '../types/errors'; import * as log from '../logging/log'; import { drop } from '../util/drop'; -import { filter, size } from '../util/iterables'; import { getContactId } from '../messages/helpers'; import { handleEditMessage } from '../util/handleEditMessage'; import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; +import { + isAttachmentDownloadQueueEmpty, + registerQueueEmptyCallback, +} from '../util/attachmentDownloadQueue'; export type EditAttributesType = { conversationId: string; @@ -22,34 +25,47 @@ export type EditAttributesType = { const edits = new Map(); +function remove(edit: EditAttributesType): void { + edits.delete(edit.envelopeId); + edit.removeFromMessageReceiverCache(); +} + export function forMessage( messageAttributes: Pick< MessageAttributesType, | 'editMessageTimestamp' | 'sent_at' | 'source' - | 'sourceUuid' + | 'sourceServiceId' | 'timestamp' | 'type' > ): Array { const sentAt = getMessageSentTimestamp(messageAttributes, { log }); - const matchingEdits = filter(edits, ([_envelopeId, item]) => { + const editValues = Array.from(edits.values()); + + if (!isAttachmentDownloadQueueEmpty()) { + log.info( + 'Edits.forMessage attachmentDownloadQueue not empty, not processing edits' + ); + registerQueueEmptyCallback(flushEdits); + return []; + } + + const matchingEdits = editValues.filter(item => { return ( item.targetSentTimestamp === sentAt && item.fromId === getContactId(messageAttributes) ); }); - if (size(matchingEdits) > 0) { - const result: Array = []; + if (matchingEdits.length > 0) { const editsLogIds: Array = []; - Array.from(matchingEdits).forEach(([envelopeId, item]) => { - result.push(item); + const result = matchingEdits.map(item => { editsLogIds.push(item.message.sent_at); - edits.delete(envelopeId); - item.removeFromMessageReceiverCache(); + remove(item); + return item; }); log.info( @@ -62,11 +78,26 @@ export function forMessage( return []; } +export async function flushEdits(): Promise { + log.info('Edits.flushEdits running'); + return drop( + Promise.all(Array.from(edits.values()).map(edit => onEdit(edit))) + ); +} + export async function onEdit(edit: EditAttributesType): Promise { edits.set(edit.envelopeId, edit); const logId = `Edits.onEdit(timestamp=${edit.message.timestamp};target=${edit.targetSentTimestamp})`; + if (!isAttachmentDownloadQueueEmpty()) { + log.info( + `${logId}: attachmentDownloadQueue not empty, not processing edits` + ); + registerQueueEmptyCallback(flushEdits); + return; + } + try { // The conversation the edited message was in; we have to find it in the database // to to figure that out. @@ -99,22 +130,22 @@ export async function onEdit(edit: EditAttributesType): Promise { if (!targetMessage) { log.info(`${logId}: No message`); - return; } - const message = window.MessageController.register( + const message = window.MessageCache.__DEPRECATED$register( targetMessage.id, - targetMessage + targetMessage, + 'Edits.onEdit' ); await handleEditMessage(message.attributes, edit); - edits.delete(edit.envelopeId); - edit.removeFromMessageReceiverCache(); + remove(edit); }) ); } catch (error) { + remove(edit); log.error(`${logId} error:`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/MessageReceipts.ts b/ts/messageModifiers/MessageReceipts.ts index a022ed2199..f495e0d8fa 100644 --- a/ts/messageModifiers/MessageReceipts.ts +++ b/ts/messageModifiers/MessageReceipts.ts @@ -1,18 +1,16 @@ // Copyright 2016 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - import { isEqual } from 'lodash'; -import { Collection, Model } from 'backbone'; import type { MessageModel } from '../models/messages'; import type { MessageAttributesType } from '../model-types.d'; +import type { SendStateByConversationId } from '../messages/MessageSendState'; import { isOutgoing, isStory } from '../state/selectors/message'; import { getOwn } from '../util/getOwn'; import { missingCaseError } from '../util/missingCaseError'; import { createWaitBatcher } from '../util/waitBatcher'; -import type { UUIDStringType } from '../types/UUID'; +import type { ServiceIdString } from '../types/ServiceId'; import * as Errors from '../types/errors'; import { SendActionType, @@ -22,9 +20,11 @@ import { import type { DeleteSentProtoRecipientOptionsType } from '../sql/Interface'; import dataInterface from '../sql/Client'; import * as log from '../logging/log'; -import { getSourceUuid } from '../messages/helpers'; +import { getSourceServiceId } from '../messages/helpers'; import { queueUpdateMessage } from '../util/messageBatcher'; import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; +import { getMessageIdForLogging } from '../util/idForLogging'; +import { generateCacheKey } from './generateCacheKey'; const { deleteSentProtoRecipient } = dataInterface; @@ -35,18 +35,18 @@ export enum MessageReceiptType { } export type MessageReceiptAttributesType = { + envelopeId: string; messageSentAt: number; receiptTimestamp: number; - sourceUuid: UUIDStringType; + removeFromMessageReceiverCache: () => unknown; sourceConversationId: string; sourceDevice: number; + sourceServiceId: ServiceIdString; type: MessageReceiptType; wasSentEncrypted: boolean; }; -class MessageReceiptModel extends Model {} - -let singleton: MessageReceipts | undefined; +const receipts = new Map(); const deleteSentProtoBatcher = createWaitBatcher({ name: 'deleteSentProtoBatcher', @@ -60,8 +60,8 @@ const deleteSentProtoBatcher = createWaitBatcher({ items ); - for (const uuid of successfulPhoneNumberShares) { - const convo = window.ConversationController.get(uuid); + for (const serviceId of successfulPhoneNumberShares) { + const convo = window.ConversationController.get(serviceId); if (!convo) { continue; } @@ -78,9 +78,20 @@ const deleteSentProtoBatcher = createWaitBatcher({ }, }); +function remove(receipt: MessageReceiptAttributesType): void { + receipts.delete( + generateCacheKey({ + sender: receipt.sourceServiceId, + timestamp: receipt.messageSentAt, + type: receipt.type, + }) + ); + receipt.removeFromMessageReceiverCache(); +} + async function getTargetMessage( sourceId: string, - sourceUuid: UUIDStringType, + serviceId: ServiceIdString, messages: ReadonlyArray ): Promise { if (messages.length === 0) { @@ -91,10 +102,16 @@ async function getTargetMessage( (isOutgoing(item) || isStory(item)) && sourceId === item.conversationId ); if (message) { - return window.MessageController.register(message.id, message); + return window.MessageCache.__DEPRECATED$register( + message.id, + message, + 'MessageReceipts.getTargetMessage 1' + ); } - const groups = await window.Signal.Data.getAllGroupsInvolvingUuid(sourceUuid); + const groups = await window.Signal.Data.getAllGroupsInvolvingServiceId( + serviceId + ); const ids = groups.map(item => item.id); ids.push(sourceId); @@ -107,7 +124,11 @@ async function getTargetMessage( return null; } - return window.MessageController.register(target.id, target); + return window.MessageCache.__DEPRECATED$register( + target.id, + target, + 'MessageReceipts.getTargetMessage 2' + ); } const wasDeliveredWithSealedSender = ( @@ -121,10 +142,10 @@ const wasDeliveredWithSealedSender = ( ); const shouldDropReceipt = ( - receipt: MessageReceiptModel, + receipt: MessageReceiptAttributesType, message: MessageModel ): boolean => { - const type = receipt.get('type'); + const { type } = receipt; switch (type) { case MessageReceiptType.Delivery: return false; @@ -140,198 +161,256 @@ const shouldDropReceipt = ( } }; -export class MessageReceipts extends Collection { - static getSingleton(): MessageReceipts { - if (!singleton) { - singleton = new MessageReceipts(); - } - - return singleton; +export function forMessage( + message: MessageModel +): Array { + if (!isOutgoing(message.attributes) && !isStory(message.attributes)) { + return []; } - forMessage(message: MessageModel): Array { - if (!isOutgoing(message.attributes) && !isStory(message.attributes)) { - return []; - } + const logId = `MessageReceipts.forMessage(${getMessageIdForLogging( + message.attributes + )})`; - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); - const sourceUuid = getSourceUuid(message.attributes); - if (ourUuid !== sourceUuid) { - return []; - } + const ourAci = window.textsecure.storage.user.getCheckedAci(); + const sourceServiceId = getSourceServiceId(message.attributes); + if (ourAci !== sourceServiceId) { + return []; + } - const sentAt = getMessageSentTimestamp(message.attributes, { log }); - const receipts = this.filter( - receipt => receipt.get('messageSentAt') === sentAt - ); - if (receipts.length) { - log.info(`MessageReceipts: found early receipts for message ${sentAt}`); - this.remove(receipts); - } - return receipts.filter(receipt => { - if (shouldDropReceipt(receipt, message)) { - log.info( - `MessageReceipts: Dropping an early receipt ${receipt.get('type')} ` + - `for message ${sentAt}` - ); - return false; - } + const receiptValues = Array.from(receipts.values()); - return true; + const sentAt = getMessageSentTimestamp(message.attributes, { log }); + const result = receiptValues.filter(item => item.messageSentAt === sentAt); + if (result.length > 0) { + log.info(`${logId}: found early receipts for message ${sentAt}`); + result.forEach(receipt => { + remove(receipt); }); } - private async updateMessageSendState( - receipt: MessageReceiptModel, - message: MessageModel - ): Promise { - const messageSentAt = receipt.get('messageSentAt'); - + return result.filter(receipt => { if (shouldDropReceipt(receipt, message)) { log.info( - `MessageReceipts: Dropping a receipt ${receipt.get('type')} ` + - `for message ${messageSentAt}` + `${logId}: Dropping an early receipt ${receipt.type} for message ${sentAt}` ); - return; + return false; } - const receiptTimestamp = receipt.get('receiptTimestamp'); - const sourceConversationId = receipt.get('sourceConversationId'); - const type = receipt.get('type'); + return true; + }); +} - const oldSendStateByConversationId = - message.get('sendStateByConversationId') || {}; - const oldSendState = getOwn( +function getNewSendStateByConversationId( + oldSendStateByConversationId: SendStateByConversationId, + receipt: MessageReceiptAttributesType +): SendStateByConversationId { + const { receiptTimestamp, sourceConversationId, type } = receipt; + + const oldSendState = getOwn( + oldSendStateByConversationId, + sourceConversationId + ) ?? { status: SendStatus.Sent, updatedAt: undefined }; + + let sendActionType: SendActionType; + switch (type) { + case MessageReceiptType.Delivery: + sendActionType = SendActionType.GotDeliveryReceipt; + break; + case MessageReceiptType.Read: + sendActionType = SendActionType.GotReadReceipt; + break; + case MessageReceiptType.View: + sendActionType = SendActionType.GotViewedReceipt; + break; + default: + throw missingCaseError(type); + } + + const newSendState = sendStateReducer(oldSendState, { + type: sendActionType, + updatedAt: receiptTimestamp, + }); + + return { + ...oldSendStateByConversationId, + [sourceConversationId]: newSendState, + }; +} + +async function updateMessageSendState( + receipt: MessageReceiptAttributesType, + message: MessageModel +): Promise { + const { messageSentAt } = receipt; + const logId = `MessageReceipts.updateMessageSendState(sentAt=${receipt.messageSentAt})`; + + if (shouldDropReceipt(receipt, message)) { + log.info( + `${logId}: Dropping a receipt ${receipt.type} for message ${messageSentAt}` + ); + return; + } + + let hasChanges = false; + + const editHistory = message.get('editHistory') ?? []; + const newEditHistory = editHistory?.map(edit => { + if (messageSentAt !== edit.timestamp) { + return edit; + } + + const oldSendStateByConversationId = edit.sendStateByConversationId ?? {}; + const newSendStateByConversationId = getNewSendStateByConversationId( oldSendStateByConversationId, - sourceConversationId - ) ?? { status: SendStatus.Sent, updatedAt: undefined }; + receipt + ); - let sendActionType: SendActionType; - switch (type) { - case MessageReceiptType.Delivery: - sendActionType = SendActionType.GotDeliveryReceipt; - break; - case MessageReceiptType.Read: - sendActionType = SendActionType.GotReadReceipt; - break; - case MessageReceiptType.View: - sendActionType = SendActionType.GotViewedReceipt; - break; - default: - throw missingCaseError(type); - } + return { + ...edit, + sendStateByConversationId: newSendStateByConversationId, + }; + }); + if (!isEqual(newEditHistory, editHistory)) { + message.set('editHistory', newEditHistory); + hasChanges = true; + } - const newSendState = sendStateReducer(oldSendState, { - type: sendActionType, - updatedAt: receiptTimestamp, - }); + const editMessageTimestamp = message.get('editMessageTimestamp'); + if ( + (!editMessageTimestamp && messageSentAt === message.get('timestamp')) || + messageSentAt === editMessageTimestamp + ) { + const oldSendStateByConversationId = + message.get('sendStateByConversationId') ?? {}; + const newSendStateByConversationId = getNewSendStateByConversationId( + oldSendStateByConversationId, + receipt + ); // The send state may not change. For example, this can happen if we get a read // receipt before a delivery receipt. - if (!isEqual(oldSendState, newSendState)) { - message.set('sendStateByConversationId', { - ...oldSendStateByConversationId, - [sourceConversationId]: newSendState, - }); - - queueUpdateMessage(message.attributes); - - // notify frontend listeners - const conversation = window.ConversationController.get( - message.get('conversationId') - ); - const updateLeftPane = conversation - ? conversation.debouncedUpdateLastMessage - : undefined; - if (updateLeftPane) { - updateLeftPane(); - } - } - - if ( - (type === MessageReceiptType.Delivery && - wasDeliveredWithSealedSender(sourceConversationId, message) && - receipt.get('wasSentEncrypted')) || - type === MessageReceiptType.Read - ) { - const recipient = window.ConversationController.get(sourceConversationId); - const recipientUuid = recipient?.get('uuid'); - const deviceId = receipt.get('sourceDevice'); - - if (recipientUuid && deviceId) { - await Promise.all([ - deleteSentProtoBatcher.add({ - timestamp: messageSentAt, - recipientUuid, - deviceId, - }), - - // We want the above call to not be delayed when testing with - // CI. - window.SignalCI - ? deleteSentProtoBatcher.flushAndWait() - : Promise.resolve(), - ]); - } else { - log.warn( - `MessageReceipts.onReceipt: Missing uuid or deviceId for deliveredTo ${sourceConversationId}` - ); - } + if (!isEqual(oldSendStateByConversationId, newSendStateByConversationId)) { + message.set('sendStateByConversationId', newSendStateByConversationId); + hasChanges = true; } } - async onReceipt(receipt: MessageReceiptModel): Promise { - const messageSentAt = receipt.get('messageSentAt'); - const sourceConversationId = receipt.get('sourceConversationId'); - const sourceUuid = receipt.get('sourceUuid'); - const type = receipt.get('type'); + if (hasChanges) { + queueUpdateMessage(message.attributes); - try { - const messages = await window.Signal.Data.getMessagesBySentAt( - messageSentAt + // notify frontend listeners + const conversation = window.ConversationController.get( + message.get('conversationId') + ); + const updateLeftPane = conversation + ? conversation.debouncedUpdateLastMessage + : undefined; + if (updateLeftPane) { + updateLeftPane(); + } + } + + const { sourceConversationId, type } = receipt; + + if ( + (type === MessageReceiptType.Delivery && + wasDeliveredWithSealedSender(sourceConversationId, message) && + receipt.wasSentEncrypted) || + type === MessageReceiptType.Read + ) { + const recipient = window.ConversationController.get(sourceConversationId); + const recipientServiceId = recipient?.getServiceId(); + const deviceId = receipt.sourceDevice; + + if (recipientServiceId && deviceId) { + await Promise.all([ + deleteSentProtoBatcher.add({ + timestamp: messageSentAt, + recipientServiceId, + deviceId, + }), + + // We want the above call to not be delayed when testing with + // CI. + window.SignalCI + ? deleteSentProtoBatcher.flushAndWait() + : Promise.resolve(), + ]); + } else { + log.warn( + `${logId}: Missing serviceId or deviceId for deliveredTo ${sourceConversationId}` ); - - const message = await getTargetMessage( - sourceConversationId, - sourceUuid, - messages - ); - - if (message) { - await this.updateMessageSendState(receipt, message); - } else { - // We didn't find any messages but maybe it's a story sent message - const targetMessages = messages.filter( - item => - item.storyDistributionListId && - item.sendStateByConversationId && - !item.deletedForEveryone && - Boolean(item.sendStateByConversationId[sourceConversationId]) - ); - - // Nope, no target message was found - if (!targetMessages.length) { - log.info( - 'MessageReceipts: No message for receipt', - type, - sourceConversationId, - sourceUuid, - messageSentAt - ); - return; - } - - await Promise.all( - targetMessages.map(msg => { - const model = window.MessageController.register(msg.id, msg); - return this.updateMessageSendState(receipt, model); - }) - ); - } - - this.remove(receipt); - } catch (error) { - log.error('MessageReceipts.onReceipt error:', Errors.toLogFormat(error)); } } } + +export async function onReceipt( + receipt: MessageReceiptAttributesType +): Promise { + receipts.set( + generateCacheKey({ + sender: receipt.sourceServiceId, + timestamp: receipt.messageSentAt, + type: receipt.type, + }), + receipt + ); + + const { messageSentAt, sourceConversationId, sourceServiceId, type } = + receipt; + + const logId = `MessageReceipts.onReceipt(sentAt=${receipt.messageSentAt})`; + + try { + const messages = await window.Signal.Data.getMessagesBySentAt( + messageSentAt + ); + + const message = await getTargetMessage( + sourceConversationId, + sourceServiceId, + messages + ); + + if (message) { + await updateMessageSendState(receipt, message); + } else { + // We didn't find any messages but maybe it's a story sent message + const targetMessages = messages.filter( + item => + item.storyDistributionListId && + item.sendStateByConversationId && + !item.deletedForEveryone && + Boolean(item.sendStateByConversationId[sourceConversationId]) + ); + + // Nope, no target message was found + if (!targetMessages.length) { + log.info( + `${logId}: No message for receipt`, + type, + sourceConversationId, + sourceServiceId + ); + return; + } + + await Promise.all( + targetMessages.map(msg => { + const model = window.MessageCache.__DEPRECATED$register( + msg.id, + msg, + 'MessageReceipts.onReceipt' + ); + return updateMessageSendState(receipt, model); + }) + ); + } + + remove(receipt); + } catch (error) { + remove(receipt); + log.error(`${logId} error:`, Errors.toLogFormat(error)); + } +} diff --git a/ts/messageModifiers/MessageRequests.ts b/ts/messageModifiers/MessageRequests.ts index b5dff9aaaa..55b823337c 100644 --- a/ts/messageModifiers/MessageRequests.ts +++ b/ts/messageModifiers/MessageRequests.ts @@ -1,111 +1,115 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - -import { Collection, Model } from 'backbone'; +import type { AciString } from '../types/ServiceId'; import type { ConversationModel } from '../models/conversations'; -import * as log from '../logging/log'; import * as Errors from '../types/errors'; +import * as log from '../logging/log'; +import { drop } from '../util/drop'; +import { getConversationIdForLogging } from '../util/idForLogging'; export type MessageRequestAttributesType = { - threadE164?: string; - threadUuid?: string; + envelopeId: string; groupV2Id?: string; + removeFromMessageReceiverCache: () => unknown; + threadAci?: AciString; + threadE164?: string; type: number; }; -class MessageRequestModel extends Model {} +const messageRequests = new Map(); -let singleton: MessageRequests | undefined; +function remove(sync: MessageRequestAttributesType): void { + messageRequests.delete(sync.envelopeId); + sync.removeFromMessageReceiverCache(); +} -export class MessageRequests extends Collection { - static getSingleton(): MessageRequests { - if (!singleton) { - singleton = new MessageRequests(); +export function forConversation( + conversation: ConversationModel +): MessageRequestAttributesType | null { + const logId = `MessageRequests.forConversation(${getConversationIdForLogging( + conversation.attributes + )})`; + + const messageRequestValues = Array.from(messageRequests.values()); + + if (conversation.get('e164')) { + const syncByE164 = messageRequestValues.find( + item => item.threadE164 === conversation.get('e164') + ); + if (syncByE164) { + log.info(`${logId}: Found early message request response for E164`); + remove(syncByE164); + return syncByE164; } - - return singleton; } - forConversation(conversation: ConversationModel): MessageRequestModel | null { - if (conversation.get('e164')) { - const syncByE164 = this.findWhere({ - threadE164: conversation.get('e164'), - }); - if (syncByE164) { - log.info( - `Found early message request response for E164 ${conversation.idForLogging()}` - ); - this.remove(syncByE164); - return syncByE164; - } + if (conversation.getServiceId()) { + const syncByServiceId = messageRequestValues.find( + item => item.threadAci === conversation.getServiceId() + ); + if (syncByServiceId) { + log.info(`${logId}: Found early message request response for serviceId`); + remove(syncByServiceId); + return syncByServiceId; } - - if (conversation.get('uuid')) { - const syncByUuid = this.findWhere({ - threadUuid: conversation.get('uuid'), - }); - if (syncByUuid) { - log.info( - `Found early message request response for UUID ${conversation.idForLogging()}` - ); - this.remove(syncByUuid); - return syncByUuid; - } - } - - // V2 group - if (conversation.get('groupId')) { - const syncByGroupId = this.findWhere({ - groupV2Id: conversation.get('groupId'), - }); - if (syncByGroupId) { - log.info( - `Found early message request response for group v2 ID ${conversation.idForLogging()}` - ); - this.remove(syncByGroupId); - return syncByGroupId; - } - } - - return null; } - async onResponse(sync: MessageRequestModel): Promise { - try { - const threadE164 = sync.get('threadE164'); - const threadUuid = sync.get('threadUuid'); - const groupV2Id = sync.get('groupV2Id'); + // V2 group + if (conversation.get('groupId')) { + const syncByGroupId = messageRequestValues.find( + item => item.groupV2Id === conversation.get('groupId') + ); + if (syncByGroupId) { + log.info(`${logId}: Found early message request response for gv2`); + remove(syncByGroupId); + return syncByGroupId; + } + } - let conversation; + return null; +} - // We multiplex between GV1/GV2 groups here, but we don't kick off migrations - if (groupV2Id) { - conversation = window.ConversationController.get(groupV2Id); - } - if (!conversation && (threadE164 || threadUuid)) { - conversation = window.ConversationController.lookupOrCreate({ - e164: threadE164, - uuid: threadUuid, - reason: 'MessageRequests.onResponse', - }); - } +export async function onResponse( + sync: MessageRequestAttributesType +): Promise { + messageRequests.set(sync.envelopeId, sync); + const { threadE164, threadAci, groupV2Id } = sync; - if (!conversation) { - log.warn( - `Received message request response for unknown conversation: groupv2(${groupV2Id}) ${threadUuid} ${threadE164}` - ); - return; - } + const logId = `MessageRequests.onResponse(groupv2(${groupV2Id}) ${threadAci} ${threadE164})`; - void conversation.applyMessageRequestResponse(sync.get('type'), { + try { + let conversation; + + // We multiplex between GV1/GV2 groups here, but we don't kick off migrations + if (groupV2Id) { + conversation = window.ConversationController.get(groupV2Id); + } + if (!conversation && (threadE164 || threadAci)) { + conversation = window.ConversationController.lookupOrCreate({ + e164: threadE164, + serviceId: threadAci, + reason: logId, + }); + } + + if (!conversation) { + log.warn( + `${logId}: received message request response for unknown conversation` + ); + remove(sync); + return; + } + + drop( + conversation.applyMessageRequestResponse(sync.type, { fromSync: true, - }); + }) + ); - this.remove(sync); - } catch (error) { - log.error('MessageRequests.onResponse error:', Errors.toLogFormat(error)); - } + remove(sync); + } catch (error) { + remove(sync); + log.error(`${logId} error:`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/Reactions.ts b/ts/messageModifiers/Reactions.ts index 6fdfe4aa4a..4918e50388 100644 --- a/ts/messageModifiers/Reactions.ts +++ b/ts/messageModifiers/Reactions.ts @@ -1,197 +1,221 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - -import { Collection, Model } from 'backbone'; +import type { AciString } from '../types/ServiceId'; import type { ConversationModel } from '../models/conversations'; +import type { MessageAttributesType } from '../model-types.d'; import type { MessageModel } from '../models/messages'; -import type { - MessageAttributesType, - ReactionAttributesType, -} from '../model-types.d'; +import type { ReactionSource } from '../reactions/ReactionSource'; import * as Errors from '../types/errors'; import * as log from '../logging/log'; import { getContactId, getContact } from '../messages/helpers'; +import { getMessageIdForLogging } from '../util/idForLogging'; +import { getMessageSentTimestampSet } from '../util/getMessageSentTimestampSet'; import { isDirectConversation, isMe } from '../util/whatTypeOfConversation'; import { isOutgoing, isStory } from '../state/selectors/message'; import { strictAssert } from '../util/assert'; -import { getMessageSentTimestampSet } from '../util/getMessageSentTimestampSet'; -export class ReactionModel extends Model {} +export type ReactionAttributesType = { + emoji: string; + envelopeId: string; + fromId: string; + remove?: boolean; + removeFromMessageReceiverCache: () => unknown; + source: ReactionSource; + // Necessary to put 1:1 story replies into the right conversation - not the same + // conversation as the target message! + storyReactionMessage?: MessageModel; + targetAuthorAci: AciString; + targetTimestamp: number; + timestamp: number; +}; -let singleton: Reactions | undefined; +const reactions = new Map(); -export class Reactions extends Collection { - static getSingleton(): Reactions { - if (!singleton) { - singleton = new Reactions(); - } +function remove(reaction: ReactionAttributesType): void { + reactions.delete(reaction.envelopeId); + reaction.removeFromMessageReceiverCache(); +} - return singleton; - } +export function forMessage( + message: MessageModel +): Array { + const logId = `Reactions.forMessage(${getMessageIdForLogging( + message.attributes + )})`; - forMessage(message: MessageModel): Array { - const sentTimestamps = getMessageSentTimestampSet(message.attributes); - if (isOutgoing(message.attributes)) { - const outgoingReactions = this.filter(item => - sentTimestamps.has(item.get('targetTimestamp')) - ); - - if (outgoingReactions.length > 0) { - log.info('Found early reaction for outgoing message'); - this.remove(outgoingReactions); - return outgoingReactions; - } - } - - const senderId = getContactId(message.attributes); - const reactionsBySource = this.filter(re => { - const targetSender = window.ConversationController.lookupOrCreate({ - uuid: re.get('targetAuthorUuid'), - reason: 'Reactions.forMessage', - }); - const targetTimestamp = re.get('targetTimestamp'); - return ( - targetSender?.id === senderId && sentTimestamps.has(targetTimestamp) - ); - }); - - if (reactionsBySource.length > 0) { - log.info('Found early reaction for message'); - this.remove(reactionsBySource); - return reactionsBySource; - } - - return []; - } - - private async findMessage( - targetTimestamp: number, - targetConversationId: string - ): Promise { - const messages = await window.Signal.Data.getMessagesBySentAt( - targetTimestamp + const reactionValues = Array.from(reactions.values()); + const sentTimestamps = getMessageSentTimestampSet(message.attributes); + if (isOutgoing(message.attributes)) { + const outgoingReactions = reactionValues.filter(item => + sentTimestamps.has(item.targetTimestamp) ); - return messages.find(m => { - const contact = getContact(m); - - if (!contact) { - return false; - } - - const mcid = contact.get('id'); - return mcid === targetConversationId; - }); + if (outgoingReactions.length > 0) { + log.info(`${logId}: Found early reaction for outgoing message`); + outgoingReactions.forEach(item => { + remove(item); + }); + return outgoingReactions; + } } - async onReaction(reaction: ReactionModel): Promise { - try { - // The conversation the target message was in; we have to find it in the database - // to to figure that out. - const targetAuthorConversation = - window.ConversationController.lookupOrCreate({ - uuid: reaction.get('targetAuthorUuid'), - reason: 'Reactions.onReaction', - }); - const targetConversationId = targetAuthorConversation?.id; - if (!targetConversationId) { - throw new Error( - 'onReaction: No conversationId returned from lookupOrCreate!' + const senderId = getContactId(message.attributes); + const reactionsBySource = reactionValues.filter(re => { + const targetSender = window.ConversationController.lookupOrCreate({ + serviceId: re.targetAuthorAci, + reason: logId, + }); + return ( + targetSender?.id === senderId && sentTimestamps.has(re.targetTimestamp) + ); + }); + + if (reactionsBySource.length > 0) { + log.info(`${logId}: Found early reaction for message`); + reactionsBySource.forEach(item => { + remove(item); + item.removeFromMessageReceiverCache(); + }); + return reactionsBySource; + } + + return []; +} + +async function findMessage( + targetTimestamp: number, + targetConversationId: string +): Promise { + const messages = await window.Signal.Data.getMessagesBySentAt( + targetTimestamp + ); + + return messages.find(m => { + const contact = getContact(m); + + if (!contact) { + return false; + } + + const mcid = contact.get('id'); + return mcid === targetConversationId; + }); +} + +export async function onReaction( + reaction: ReactionAttributesType +): Promise { + reactions.set(reaction.envelopeId, reaction); + + const logId = `Reactions.onReaction(timestamp=${reaction.timestamp};target=${reaction.targetTimestamp})`; + + try { + // The conversation the target message was in; we have to find it in the database + // to to figure that out. + const targetAuthorConversation = + window.ConversationController.lookupOrCreate({ + serviceId: reaction.targetAuthorAci, + reason: logId, + }); + const targetConversationId = targetAuthorConversation?.id; + if (!targetConversationId) { + throw new Error( + `${logId} Error: No conversationId returned from lookupOrCreate!` + ); + } + + const generatedMessage = reaction.storyReactionMessage; + strictAssert( + generatedMessage, + `${logId} strictAssert: Story reactions must provide storyReactionMessage` + ); + const fromConversation = window.ConversationController.get( + generatedMessage.get('conversationId') + ); + + let targetConversation: ConversationModel | undefined | null; + + const targetMessageCheck = await findMessage( + reaction.targetTimestamp, + targetConversationId + ); + if (!targetMessageCheck) { + log.info( + `${logId}: No message for reaction`, + 'targeting', + reaction.targetAuthorAci + ); + return; + } + + if ( + fromConversation && + isStory(targetMessageCheck) && + isDirectConversation(fromConversation.attributes) && + !isMe(fromConversation.attributes) + ) { + targetConversation = fromConversation; + } else { + targetConversation = + await window.ConversationController.getConversationForTargetMessage( + targetConversationId, + reaction.targetTimestamp ); - } + } - const generatedMessage = reaction.get('storyReactionMessage'); - strictAssert( - generatedMessage, - 'Story reactions must provide storyReactionMessage' - ); - const fromConversation = window.ConversationController.get( - generatedMessage.get('conversationId') + if (!targetConversation) { + log.info( + `${logId}: No target conversation for reaction`, + reaction.targetAuthorAci, + reaction.targetTimestamp ); + remove(reaction); + return undefined; + } - let targetConversation: ConversationModel | undefined | null; - - const targetMessageCheck = await this.findMessage( - reaction.get('targetTimestamp'), - targetConversationId - ); - if (!targetMessageCheck) { - log.info( - 'No message for reaction', - reaction.get('timestamp'), - 'targeting', - reaction.get('targetAuthorUuid'), - reaction.get('targetTimestamp') - ); + // awaiting is safe since `onReaction` is never called from inside the queue + await targetConversation.queueJob('Reactions.onReaction', async () => { + log.info(`${logId}: handling`); + // Thanks TS. + if (!targetConversation) { + remove(reaction); return; } - if ( - fromConversation && - isStory(targetMessageCheck) && - isDirectConversation(fromConversation.attributes) && - !isMe(fromConversation.attributes) - ) { - targetConversation = fromConversation; + // Message is fetched inside the conversation queue so we have the + // most recent data + const targetMessage = await findMessage( + reaction.targetTimestamp, + targetConversationId + ); + + if (!targetMessage) { + remove(reaction); + return; + } + + const message = window.MessageCache.__DEPRECATED$register( + targetMessage.id, + targetMessage, + 'Reactions.onReaction' + ); + + // Use the generated message in ts/background.ts to create a message + // if the reaction is targeted at a story. + if (!isStory(targetMessage)) { + await message.handleReaction(reaction); } else { - targetConversation = - await window.ConversationController.getConversationForTargetMessage( - targetConversationId, - reaction.get('targetTimestamp') - ); + await generatedMessage.handleReaction(reaction, { + storyMessage: targetMessage, + }); } - if (!targetConversation) { - log.info( - 'No target conversation for reaction', - reaction.get('targetAuthorUuid'), - reaction.get('targetTimestamp') - ); - return undefined; - } - - // awaiting is safe since `onReaction` is never called from inside the queue - await targetConversation.queueJob('Reactions.onReaction', async () => { - log.info('Handling reaction for', reaction.get('targetTimestamp')); - - // Thanks TS. - if (!targetConversation) { - return; - } - - // Message is fetched inside the conversation queue so we have the - // most recent data - const targetMessage = await this.findMessage( - reaction.get('targetTimestamp'), - targetConversationId - ); - - if (!targetMessage) { - return; - } - - const message = window.MessageController.register( - targetMessage.id, - targetMessage - ); - - // Use the generated message in ts/background.ts to create a message - // if the reaction is targeted at a story. - if (!isStory(targetMessage)) { - await message.handleReaction(reaction); - } else { - await generatedMessage.handleReaction(reaction, { - storyMessage: targetMessage, - }); - } - - this.remove(reaction); - }); - } catch (error) { - log.error('Reactions.onReaction error:', Errors.toLogFormat(error)); - } + remove(reaction); + }); + } catch (error) { + remove(reaction); + log.error(`${logId} error:`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/ReadSyncs.ts b/ts/messageModifiers/ReadSyncs.ts index ded90293c9..71db8c548c 100644 --- a/ts/messageModifiers/ReadSyncs.ts +++ b/ts/messageModifiers/ReadSyncs.ts @@ -1,160 +1,201 @@ // Copyright 2017 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - -import { Collection, Model } from 'backbone'; - +import type { AciString } from '../types/ServiceId'; import type { MessageModel } from '../models/messages'; +import * as Errors from '../types/errors'; +import * as log from '../logging/log'; +import { StartupQueue } from '../util/StartupQueue'; +import { drop } from '../util/drop'; +import { getMessageIdForLogging } from '../util/idForLogging'; +import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; import { isIncoming } from '../state/selectors/message'; import { isMessageUnread } from '../util/isMessageUnread'; import { notificationService } from '../services/notifications'; -import * as log from '../logging/log'; -import * as Errors from '../types/errors'; -import { StartupQueue } from '../util/StartupQueue'; import { queueUpdateMessage } from '../util/messageBatcher'; -import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; +import { strictAssert } from '../util/assert'; +import { generateCacheKey } from './generateCacheKey'; export type ReadSyncAttributesType = { - senderId: string; - sender?: string; - senderUuid: string; - timestamp: number; + envelopeId: string; readAt: number; + removeFromMessageReceiverCache: () => unknown; + sender?: string; + senderAci: AciString; + senderId: string; + timestamp: number; }; -class ReadSyncModel extends Model {} +const readSyncs = new Map(); -let singleton: ReadSyncs | undefined; +function remove(sync: ReadSyncAttributesType): void { + readSyncs.delete( + generateCacheKey({ + sender: sync.senderId, + timestamp: sync.timestamp, + type: 'readsync', + }) + ); + sync.removeFromMessageReceiverCache(); +} + +async function maybeItIsAReactionReadSync( + sync: ReadSyncAttributesType +): Promise { + const logId = `ReadSyncs.onSync(timestamp=${sync.timestamp})`; -async function maybeItIsAReactionReadSync(sync: ReadSyncModel): Promise { const readReaction = await window.Signal.Data.markReactionAsRead( - sync.get('senderUuid'), - Number(sync.get('timestamp')) + sync.senderAci, + Number(sync.timestamp) ); - if (!readReaction) { - log.info( - 'Nothing found for read sync', - sync.get('senderId'), - sync.get('sender'), - sync.get('senderUuid'), - sync.get('timestamp') - ); + if ( + !readReaction || + readReaction?.targetAuthorAci !== window.storage.user.getCheckedAci() + ) { + log.info(`${logId} not found:`, sync.senderId, sync.sender, sync.senderAci); return; } + log.info( + `${logId} read reaction sync found:`, + readReaction.conversationId, + sync.senderId, + sync.sender, + sync.senderAci + ); + + remove(sync); + notificationService.removeBy({ conversationId: readReaction.conversationId, emoji: readReaction.emoji, - targetAuthorUuid: readReaction.targetAuthorUuid, + targetAuthorAci: readReaction.targetAuthorAci, targetTimestamp: readReaction.targetTimestamp, }); } -export class ReadSyncs extends Collection { - static getSingleton(): ReadSyncs { - if (!singleton) { - singleton = new ReadSyncs(); - } +export function forMessage( + message: MessageModel +): ReadSyncAttributesType | null { + const logId = `ReadSyncs.forMessage(${getMessageIdForLogging( + message.attributes + )})`; - return singleton; + const sender = window.ConversationController.lookupOrCreate({ + e164: message.get('source'), + serviceId: message.get('sourceServiceId'), + reason: logId, + }); + const messageTimestamp = getMessageSentTimestamp(message.attributes, { + log, + }); + const readSyncValues = Array.from(readSyncs.values()); + const foundSync = readSyncValues.find(item => { + return item.senderId === sender?.id && item.timestamp === messageTimestamp; + }); + if (foundSync) { + log.info( + `${logId}: Found early read sync for message ${foundSync.timestamp}` + ); + remove(foundSync); + return foundSync; } - forMessage(message: MessageModel): ReadSyncModel | null { - const sender = window.ConversationController.lookupOrCreate({ - e164: message.get('source'), - uuid: message.get('sourceUuid'), - reason: 'ReadSyncs.forMessage', - }); - const messageTimestamp = getMessageSentTimestamp(message.attributes, { - log, - }); - const sync = this.find(item => { - return ( - item.get('senderId') === sender?.id && - item.get('timestamp') === messageTimestamp - ); - }); - if (sync) { - log.info(`Found early read sync for message ${sync.get('timestamp')}`); - this.remove(sync); - return sync; - } + return null; +} - return null; - } +export async function onSync(sync: ReadSyncAttributesType): Promise { + readSyncs.set( + generateCacheKey({ + sender: sync.senderId, + timestamp: sync.timestamp, + type: 'readsync', + }), + sync + ); - async onSync(sync: ReadSyncModel): Promise { - try { - const messages = await window.Signal.Data.getMessagesBySentAt( - sync.get('timestamp') - ); + const logId = `ReadSyncs.onSync(timestamp=${sync.timestamp})`; - const found = messages.find(item => { - const sender = window.ConversationController.lookupOrCreate({ - e164: item.source, - uuid: item.sourceUuid, - reason: 'ReadSyncs.onSync', - }); + try { + const messages = await window.Signal.Data.getMessagesBySentAt( + sync.timestamp + ); - return isIncoming(item) && sender?.id === sync.get('senderId'); + const found = messages.find(item => { + const sender = window.ConversationController.lookupOrCreate({ + e164: item.source, + serviceId: item.sourceServiceId, + reason: logId, }); - if (!found) { - await maybeItIsAReactionReadSync(sync); - return; - } + return isIncoming(item) && sender?.id === sync.senderId; + }); - notificationService.removeBy({ messageId: found.id }); - - const message = window.MessageController.register(found.id, found); - const readAt = Math.min(sync.get('readAt'), Date.now()); - - // If message is unread, we mark it read. Otherwise, we update the expiration - // timer to the time specified by the read sync if it's earlier than - // the previous read time. - if (isMessageUnread(message.attributes)) { - // TODO DESKTOP-1509: use MessageUpdater.markRead once this is TS - message.markRead(readAt, { skipSave: true }); - - const updateConversation = async () => { - // onReadMessage may result in messages older than this one being - // marked read. We want those messages to have the same expire timer - // start time as this one, so we pass the readAt value through. - void message.getConversation()?.onReadMessage(message, readAt); - }; - - // only available during initialization - if (StartupQueue.isAvailable()) { - const conversation = message.getConversation(); - if (conversation) { - StartupQueue.add( - conversation.get('id'), - message.get('sent_at'), - updateConversation - ); - } - } else { - // not awaiting since we don't want to block work happening in the - // eventHandlerQueue - void updateConversation(); - } - } else { - const now = Date.now(); - const existingTimestamp = message.get('expirationStartTimestamp'); - const expirationStartTimestamp = Math.min( - now, - Math.min(existingTimestamp || now, readAt || now) - ); - message.set({ expirationStartTimestamp }); - } - - queueUpdateMessage(message.attributes); - - this.remove(sync); - } catch (error) { - log.error('ReadSyncs.onSync error:', Errors.toLogFormat(error)); + if (!found) { + await maybeItIsAReactionReadSync(sync); + return; } + + notificationService.removeBy({ messageId: found.id }); + + const message = window.MessageCache.__DEPRECATED$register( + found.id, + found, + 'ReadSyncs.onSync' + ); + const readAt = Math.min(sync.readAt, Date.now()); + const newestSentAt = sync.timestamp; + + // If message is unread, we mark it read. Otherwise, we update the expiration + // timer to the time specified by the read sync if it's earlier than + // the previous read time. + if (isMessageUnread(message.attributes)) { + // TODO DESKTOP-1509: use MessageUpdater.markRead once this is TS + message.markRead(readAt, { skipSave: true }); + + const updateConversation = async () => { + const conversation = message.getConversation(); + strictAssert(conversation, `${logId}: conversation not found`); + // onReadMessage may result in messages older than this one being + // marked read. We want those messages to have the same expire timer + // start time as this one, so we pass the readAt value through. + drop(conversation.onReadMessage(message, readAt, newestSentAt)); + }; + + // only available during initialization + if (StartupQueue.isAvailable()) { + const conversation = message.getConversation(); + strictAssert( + conversation, + `${logId}: conversation not found (StartupQueue)` + ); + StartupQueue.add( + conversation.get('id'), + message.get('sent_at'), + updateConversation + ); + } else { + // not awaiting since we don't want to block work happening in the + // eventHandlerQueue + drop(updateConversation()); + } + } else { + log.info(`${logId}: updating expiration`); + const now = Date.now(); + const existingTimestamp = message.get('expirationStartTimestamp'); + const expirationStartTimestamp = Math.min( + now, + Math.min(existingTimestamp || now, readAt || now) + ); + message.set({ expirationStartTimestamp }); + } + + queueUpdateMessage(message.attributes); + + remove(sync); + } catch (error) { + remove(sync); + log.error(`${logId} error:`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/ViewOnceOpenSyncs.ts b/ts/messageModifiers/ViewOnceOpenSyncs.ts index c3f896611a..43d206ec7d 100644 --- a/ts/messageModifiers/ViewOnceOpenSyncs.ts +++ b/ts/messageModifiers/ViewOnceOpenSyncs.ts @@ -1,101 +1,112 @@ // Copyright 2019 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - -import { Collection, Model } from 'backbone'; +import type { AciString } from '../types/ServiceId'; import type { MessageModel } from '../models/messages'; -import * as log from '../logging/log'; import * as Errors from '../types/errors'; +import * as log from '../logging/log'; +import { getMessageIdForLogging } from '../util/idForLogging'; export type ViewOnceOpenSyncAttributesType = { + removeFromMessageReceiverCache: () => unknown; source?: string; - sourceUuid: string; + sourceAci: AciString; timestamp: number; }; -class ViewOnceOpenSyncModel extends Model {} +const viewOnceSyncs = new Map(); -let singleton: ViewOnceOpenSyncs | undefined; +function remove(sync: ViewOnceOpenSyncAttributesType): void { + viewOnceSyncs.delete(sync.timestamp); + sync.removeFromMessageReceiverCache(); +} -export class ViewOnceOpenSyncs extends Collection { - static getSingleton(): ViewOnceOpenSyncs { - if (!singleton) { - singleton = new ViewOnceOpenSyncs(); - } +export function forMessage( + message: MessageModel +): ViewOnceOpenSyncAttributesType | null { + const logId = `ViewOnceOpenSyncs.forMessage(${getMessageIdForLogging( + message.attributes + )})`; - return singleton; + const viewOnceSyncValues = Array.from(viewOnceSyncs.values()); + + const syncBySourceServiceId = viewOnceSyncValues.find(item => { + return ( + item.sourceAci === message.get('sourceServiceId') && + item.timestamp === message.get('sent_at') + ); + }); + + if (syncBySourceServiceId) { + log.info(`${logId}: Found early view once open sync for message`); + remove(syncBySourceServiceId); + return syncBySourceServiceId; } - forMessage(message: MessageModel): ViewOnceOpenSyncModel | null { - const syncBySourceUuid = this.find(item => { - return ( - item.get('sourceUuid') === message.get('sourceUuid') && - item.get('timestamp') === message.get('sent_at') - ); - }); - if (syncBySourceUuid) { - log.info('Found early view once open sync for message'); - this.remove(syncBySourceUuid); - return syncBySourceUuid; - } - - const syncBySource = this.find(item => { - return ( - item.get('source') === message.get('source') && - item.get('timestamp') === message.get('sent_at') - ); - }); - if (syncBySource) { - log.info('Found early view once open sync for message'); - this.remove(syncBySource); - return syncBySource; - } - - return null; + const syncBySource = viewOnceSyncValues.find(item => { + return ( + item.source === message.get('source') && + item.timestamp === message.get('sent_at') + ); + }); + if (syncBySource) { + log.info(`${logId}: Found early view once open sync for message`); + remove(syncBySource); + return syncBySource; } - async onSync(sync: ViewOnceOpenSyncModel): Promise { - try { - const messages = await window.Signal.Data.getMessagesBySentAt( - sync.get('timestamp') + return null; +} + +export async function onSync( + sync: ViewOnceOpenSyncAttributesType +): Promise { + viewOnceSyncs.set(sync.timestamp, sync); + + const logId = `ViewOnceOpenSyncs.onSync(timestamp=${sync.timestamp})`; + + try { + const messages = await window.Signal.Data.getMessagesBySentAt( + sync.timestamp + ); + + const found = messages.find(item => { + const itemSourceAci = item.sourceServiceId; + const syncSourceAci = sync.sourceAci; + const itemSource = item.source; + const syncSource = sync.source; + + return Boolean( + (itemSourceAci && syncSourceAci && itemSourceAci === syncSourceAci) || + (itemSource && syncSource && itemSource === syncSource) ); + }); - const found = messages.find(item => { - const itemSourceUuid = item.sourceUuid; - const syncSourceUuid = sync.get('sourceUuid'); - const itemSource = item.source; - const syncSource = sync.get('source'); + const syncSource = sync.source; + const syncSourceAci = sync.sourceAci; + const syncTimestamp = sync.timestamp; + const wasMessageFound = Boolean(found); + log.info(`${logId} receive:`, { + syncSource, + syncSourceAci, + syncTimestamp, + wasMessageFound, + }); - return Boolean( - (itemSourceUuid && - syncSourceUuid && - itemSourceUuid === syncSourceUuid) || - (itemSource && syncSource && itemSource === syncSource) - ); - }); - - const syncSource = sync.get('source'); - const syncSourceUuid = sync.get('sourceUuid'); - const syncTimestamp = sync.get('timestamp'); - const wasMessageFound = Boolean(found); - log.info('Receive view once open sync:', { - syncSource, - syncSourceUuid, - syncTimestamp, - wasMessageFound, - }); - - if (!found) { - return; - } - - const message = window.MessageController.register(found.id, found); - await message.markViewOnceMessageViewed({ fromSync: true }); - - this.remove(sync); - } catch (error) { - log.error('ViewOnceOpenSyncs.onSync error:', Errors.toLogFormat(error)); + if (!found) { + return; } + + const message = window.MessageCache.__DEPRECATED$register( + found.id, + found, + 'ViewOnceOpenSyncs.onSync' + ); + await message.markViewOnceMessageViewed({ fromSync: true }); + + viewOnceSyncs.delete(sync.timestamp); + sync.removeFromMessageReceiverCache(); + } catch (error) { + log.error(`${logId} error:`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/ViewSyncs.ts b/ts/messageModifiers/ViewSyncs.ts index 29f455ae01..35c9bf1df2 100644 --- a/ts/messageModifiers/ViewSyncs.ts +++ b/ts/messageModifiers/ViewSyncs.ts @@ -1,135 +1,160 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - -import { Collection, Model } from 'backbone'; - +import type { AciString } from '../types/ServiceId'; import type { MessageModel } from '../models/messages'; -import { ReadStatus } from '../messages/MessageReadStatus'; -import { markViewed } from '../services/MessageUpdater'; -import { isDownloaded } from '../types/Attachment'; import * as Errors from '../types/errors'; -import { isIncoming } from '../state/selectors/message'; -import { notificationService } from '../services/notifications'; -import { queueAttachmentDownloads } from '../util/queueAttachmentDownloads'; import * as log from '../logging/log'; import { GiftBadgeStates } from '../components/conversation/Message'; -import { queueUpdateMessage } from '../util/messageBatcher'; +import { ReadStatus } from '../messages/MessageReadStatus'; +import { getMessageIdForLogging } from '../util/idForLogging'; import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; +import { isDownloaded } from '../types/Attachment'; +import { isIncoming } from '../state/selectors/message'; +import { markViewed } from '../services/MessageUpdater'; +import { notificationService } from '../services/notifications'; +import { queueAttachmentDownloads } from '../util/queueAttachmentDownloads'; +import { queueUpdateMessage } from '../util/messageBatcher'; +import { generateCacheKey } from './generateCacheKey'; export type ViewSyncAttributesType = { - senderId: string; + envelopeId: string; + removeFromMessageReceiverCache: () => unknown; + senderAci: AciString; senderE164?: string; - senderUuid: string; + senderId: string; timestamp: number; viewedAt: number; }; -class ViewSyncModel extends Model {} +const viewSyncs = new Map(); -let singleton: ViewSyncs | undefined; +function remove(sync: ViewSyncAttributesType): void { + viewSyncs.delete( + generateCacheKey({ + sender: sync.senderId, + timestamp: sync.timestamp, + type: 'viewsync', + }) + ); + sync.removeFromMessageReceiverCache(); +} -export class ViewSyncs extends Collection { - static getSingleton(): ViewSyncs { - if (!singleton) { - singleton = new ViewSyncs(); - } +export function forMessage( + message: MessageModel +): Array { + const logId = `ViewSyncs.forMessage(${getMessageIdForLogging( + message.attributes + )})`; - return singleton; + const sender = window.ConversationController.lookupOrCreate({ + e164: message.get('source'), + serviceId: message.get('sourceServiceId'), + reason: logId, + }); + const messageTimestamp = getMessageSentTimestamp(message.attributes, { + log, + }); + + const viewSyncValues = Array.from(viewSyncs.values()); + + const matchingSyncs = viewSyncValues.filter(item => { + return item.senderId === sender?.id && item.timestamp === messageTimestamp; + }); + + if (matchingSyncs.length > 0) { + log.info( + `${logId}: Found ${matchingSyncs.length} early view sync(s) for message ${messageTimestamp}` + ); } + matchingSyncs.forEach(sync => { + remove(sync); + }); - forMessage(message: MessageModel): Array { - const sender = window.ConversationController.lookupOrCreate({ - e164: message.get('source'), - uuid: message.get('sourceUuid'), - reason: 'ViewSyncs.forMessage', - }); - const messageTimestamp = getMessageSentTimestamp(message.attributes, { - log, - }); - const syncs = this.filter(item => { - return ( - item.get('senderId') === sender?.id && - item.get('timestamp') === messageTimestamp - ); - }); - if (syncs.length) { - log.info( - `Found ${syncs.length} early view sync(s) for message ${messageTimestamp}` - ); - this.remove(syncs); - } - return syncs; - } + return matchingSyncs; +} - async onSync(sync: ViewSyncModel): Promise { - try { - const messages = await window.Signal.Data.getMessagesBySentAt( - sync.get('timestamp') - ); +export async function onSync(sync: ViewSyncAttributesType): Promise { + viewSyncs.set( + generateCacheKey({ + sender: sync.senderId, + timestamp: sync.timestamp, + type: 'viewsync', + }), + sync + ); - const found = messages.find(item => { - const sender = window.ConversationController.lookupOrCreate({ - e164: item.source, - uuid: item.sourceUuid, - reason: 'ViewSyncs.onSync', - }); + const logId = `ViewSyncs.onSync(timestamp=${sync.timestamp})`; - return sender?.id === sync.get('senderId'); + try { + const messages = await window.Signal.Data.getMessagesBySentAt( + sync.timestamp + ); + + const found = messages.find(item => { + const sender = window.ConversationController.lookupOrCreate({ + e164: item.source, + serviceId: item.sourceServiceId, + reason: logId, }); - if (!found) { - log.info( - 'Nothing found for view sync', - sync.get('senderId'), - sync.get('senderE164'), - sync.get('senderUuid'), - sync.get('timestamp') + return sender?.id === sync.senderId; + }); + + if (!found) { + log.info( + `${logId}: nothing found`, + sync.senderId, + sync.senderE164, + sync.senderAci + ); + return; + } + + notificationService.removeBy({ messageId: found.id }); + + const message = window.MessageCache.__DEPRECATED$register( + found.id, + found, + 'ViewSyncs.onSync' + ); + let didChangeMessage = false; + + if (message.get('readStatus') !== ReadStatus.Viewed) { + didChangeMessage = true; + message.set(markViewed(message.attributes, sync.viewedAt)); + + const attachments = message.get('attachments'); + if (!attachments?.every(isDownloaded)) { + const updatedFields = await queueAttachmentDownloads( + message.attributes ); - return; - } - - notificationService.removeBy({ messageId: found.id }); - - const message = window.MessageController.register(found.id, found); - let didChangeMessage = false; - - if (message.get('readStatus') !== ReadStatus.Viewed) { - didChangeMessage = true; - message.set(markViewed(message.attributes, sync.get('viewedAt'))); - - const attachments = message.get('attachments'); - if (!attachments?.every(isDownloaded)) { - const updatedFields = await queueAttachmentDownloads( - message.attributes - ); - if (updatedFields) { - message.set(updatedFields); - } + if (updatedFields) { + message.set(updatedFields); } } - - const giftBadge = message.get('giftBadge'); - if (giftBadge) { - didChangeMessage = true; - message.set({ - giftBadge: { - ...giftBadge, - state: isIncoming(message.attributes) - ? GiftBadgeStates.Redeemed - : GiftBadgeStates.Opened, - }, - }); - } - - if (didChangeMessage) { - queueUpdateMessage(message.attributes); - } - - this.remove(sync); - } catch (error) { - log.error('ViewSyncs.onSync error:', Errors.toLogFormat(error)); } + + const giftBadge = message.get('giftBadge'); + if (giftBadge) { + didChangeMessage = true; + message.set({ + giftBadge: { + ...giftBadge, + state: isIncoming(message.attributes) + ? GiftBadgeStates.Redeemed + : GiftBadgeStates.Opened, + }, + }); + } + + if (didChangeMessage) { + queueUpdateMessage(message.attributes); + } + + remove(sync); + } catch (error) { + remove(sync); + log.error(`${logId} error:`, Errors.toLogFormat(error)); } } diff --git a/ts/messageModifiers/generateCacheKey.ts b/ts/messageModifiers/generateCacheKey.ts new file mode 100644 index 0000000000..246732e6bd --- /dev/null +++ b/ts/messageModifiers/generateCacheKey.ts @@ -0,0 +1,24 @@ +// Copyright 2016 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import type { MessageReceiptType } from './MessageReceipts'; + +// This function is necessary because the only thing we can guarantee will be unique is +// three pieces of data: sender, deviceId, and timestamp. +// Because we don't care which device interacted with our message, we collapse this down +// to: sender + timestamp. +// In some cases, modifiers are stored in the same map, so we also add the modifier type + +type ModifierType = MessageReceiptType | 'readsync' | 'viewsync'; + +export function generateCacheKey({ + sender, + timestamp, + type, +}: { + sender: string; + timestamp: number; + type: ModifierType; +}): string { + return `cacheKey-${sender}-${timestamp}-${type}`; +} diff --git a/ts/messages/getMessageById.ts b/ts/messages/getMessageById.ts index 3421641a50..20ab189299 100644 --- a/ts/messages/getMessageById.ts +++ b/ts/messages/getMessageById.ts @@ -3,13 +3,13 @@ import * as log from '../logging/log'; import type { MessageAttributesType } from '../model-types.d'; -import type { MessageModel } from '../models/messages'; import * as Errors from '../types/errors'; +import type { MessageModel } from '../models/messages'; -export async function getMessageById( +export async function __DEPRECATED$getMessageById( messageId: string ): Promise { - const message = window.MessageController.getById(messageId); + const message = window.MessageCache.__DEPRECATED$getById(messageId); if (message) { return message; } @@ -28,5 +28,9 @@ export async function getMessageById( return undefined; } - return window.MessageController.register(found.id, found); + return window.MessageCache.__DEPRECATED$register( + found.id, + found, + '__DEPRECATED$getMessageById' + ); } diff --git a/ts/messages/getMessagesById.ts b/ts/messages/getMessagesById.ts index 5038df69de..8912a214e8 100644 --- a/ts/messages/getMessagesById.ts +++ b/ts/messages/getMessagesById.ts @@ -13,7 +13,7 @@ export async function getMessagesById( const messageIdsToLookUpInDatabase: Array = []; for (const messageId of messageIds) { - const message = window.MessageController.getById(messageId); + const message = window.MessageCache.__DEPRECATED$getById(messageId); if (message) { messagesFromMemory.push(message); } else { @@ -39,7 +39,11 @@ export async function getMessagesById( // We use `window.Whisper.Message` instead of `MessageModel` here to avoid a circular // import. const message = new window.Whisper.Message(rawMessage); - return window.MessageController.register(message.id, message); + return window.MessageCache.__DEPRECATED$register( + message.id, + message, + 'getMessagesById' + ); }); return [...messagesFromMemory, ...messagesFromDatabase]; diff --git a/ts/messages/helpers.ts b/ts/messages/helpers.ts index 1573e677b9..4880b6c27c 100644 --- a/ts/messages/helpers.ts +++ b/ts/messages/helpers.ts @@ -8,7 +8,7 @@ import type { MessageAttributesType, QuotedMessageType, } from '../model-types.d'; -import type { UUIDStringType } from '../types/UUID'; +import type { ServiceIdString } from '../types/ServiceId'; import { PaymentEventKind } from '../types/Payment'; import type { AnyPaymentEvent } from '../types/Payment'; import type { LocalizerType } from '../types/Util'; @@ -111,16 +111,16 @@ export function getPaymentEventDescription( export function isQuoteAMatch( message: MessageAttributesType | null | undefined, conversationId: string, - quote: Pick + quote: Pick ): message is MessageAttributesType { if (!message) { return false; } - const { authorUuid, id } = quote; + const { authorAci, id } = quote; const authorConversation = window.ConversationController.lookupOrCreate({ e164: 'author' in quote ? quote.author : undefined, - uuid: authorUuid, + serviceId: authorAci, reason: 'helpers.isQuoteAMatch', }); @@ -137,18 +137,18 @@ export function isQuoteAMatch( } export function getContactId( - message: Pick + message: Pick ): string | undefined { const source = getSource(message); - const sourceUuid = getSourceUuid(message); + const sourceServiceId = getSourceServiceId(message); - if (!source && !sourceUuid) { + if (!source && !sourceServiceId) { return window.ConversationController.getOurConversationId(); } const conversation = window.ConversationController.lookupOrCreate({ e164: source, - uuid: sourceUuid, + serviceId: sourceServiceId, reason: 'helpers.getContactId', }); return conversation?.id; @@ -191,19 +191,19 @@ export function getSourceDevice( return sourceDevice || window.textsecure.storage.user.getDeviceId(); } -export function getSourceUuid( - message: Pick -): UUIDStringType | undefined { +export function getSourceServiceId( + message: Pick +): ServiceIdString | undefined { if (isIncoming(message) || isStory(message)) { - return message.sourceUuid; + return message.sourceServiceId; } if (!isOutgoing(message)) { log.warn( - 'Message.getSourceUuid: Called for non-incoming/non-outgoing message' + 'Message.getSourceServiceId: Called for non-incoming/non-outgoing message' ); } - return window.textsecure.storage.user.getUuid()?.toString(); + return window.textsecure.storage.user.getAci(); } export const isCustomError = (e: unknown): e is CustomError => diff --git a/ts/messages/migrateLegacySendAttributes.ts b/ts/messages/migrateLegacySendAttributes.ts index fbf012ab6f..343e8f5c05 100644 --- a/ts/messages/migrateLegacySendAttributes.ts +++ b/ts/messages/migrateLegacySendAttributes.ts @@ -5,7 +5,7 @@ import { get, isEmpty } from 'lodash'; import { getOwn } from '../util/getOwn'; import { map, concat, repeat, zipObject } from '../util/iterables'; import { isOutgoing } from '../state/selectors/message'; -import type { CustomError, MessageAttributesType } from '../model-types.d'; +import type { MessageAttributesType } from '../model-types.d'; import type { SendState, SendStateByConversationId } from './MessageSendState'; import { SendActionType, @@ -13,6 +13,11 @@ import { SendStatus, } from './MessageSendState'; +type LegacyCustomError = Error & { + identifier?: string; + number?: string; +}; + /** * This converts legacy message fields, such as `sent_to`, into the new * `sendStateByConversationId` format. These legacy fields aren't typed to prevent their @@ -130,7 +135,7 @@ export function migrateLegacySendAttributes( } function getConversationIdsFromErrors( - errors: undefined | ReadonlyArray, + errors: undefined | ReadonlyArray, getConversation: GetConversationType ): Array { const result: Array = []; diff --git a/ts/messages/migrateMessageData.ts b/ts/messages/migrateMessageData.ts index a7779c87b1..fd96386db2 100644 --- a/ts/messages/migrateMessageData.ts +++ b/ts/messages/migrateMessageData.ts @@ -7,7 +7,7 @@ import pMap from 'p-map'; import { CURRENT_SCHEMA_VERSION } from '../types/Message2'; import { isNotNil } from '../util/isNotNil'; import type { MessageAttributesType } from '../model-types.d'; -import type { UUIDStringType } from '../types/UUID'; +import type { AciString } from '../types/ServiceId'; import * as Errors from '../types/errors'; const MAX_CONCURRENCY = 5; @@ -33,7 +33,7 @@ export async function migrateMessageData({ ) => Promise>; saveMessages: ( data: ReadonlyArray, - options: { ourUuid: UUIDStringType } + options: { ourAci: AciString } ) => Promise; maxVersion?: number; }>): Promise< @@ -103,7 +103,7 @@ export async function migrateMessageData({ const saveStartTime = Date.now(); - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); + const ourAci = window.textsecure.storage.user.getCheckedAci(); await saveMessages( [ ...upgradedMessages, @@ -114,7 +114,7 @@ export async function migrateMessageData({ schemaMigrationAttempts: (message.schemaMigrationAttempts ?? 0) + 1, })), ], - { ourUuid } + { ourAci } ); const saveDuration = Date.now() - saveStartTime; diff --git a/ts/model-types.d.ts b/ts/model-types.d.ts index b128795b4c..10f90188c1 100644 --- a/ts/model-types.d.ts +++ b/ts/model-types.d.ts @@ -1,17 +1,12 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -/* eslint-disable max-classes-per-file */ - import * as Backbone from 'backbone'; import type { GroupV2ChangeType } from './groups'; import type { DraftBodyRanges, RawBodyRange } from './types/BodyRange'; -import type { CallHistoryDetailsFromDiskType } from './types/Calling'; import type { CustomColorType, ConversationColorType } from './types/Colors'; -import type { DeviceType } from './textsecure/Types.d'; import type { SendMessageChallengeData } from './textsecure/Errors'; -import type { MessageModel } from './models/messages'; import type { ConversationModel } from './models/conversations'; import type { ProfileNameChangeType } from './util/getStringForProfileChange'; import type { CapabilitiesType } from './textsecure/WebAPI'; @@ -22,9 +17,9 @@ import type { GroupNameCollisionsWithIdsByTitle } from './util/groupMemberNameCo import type { AttachmentDraftType, AttachmentType } from './types/Attachment'; import type { EmbeddedContactType } from './types/EmbeddedContact'; import { SignalService as Proto } from './protobuf'; -import type { AvatarDataType } from './types/Avatar'; -import type { UUIDStringType } from './types/UUID'; -import type { ReactionSource } from './reactions/ReactionSource'; +import type { AvatarDataType, ContactAvatarType } from './types/Avatar'; +import type { AciString, PniString, ServiceIdString } from './types/ServiceId'; +import type { StoryDistributionIdString } from './types/StoryDistributionId'; import type { SeenStatus } from './MessageSeenStatus'; import type { GiftBadgeStates } from './components/conversation/Message'; import type { LinkPreviewType } from './types/message/LinkPreviews'; @@ -48,14 +43,20 @@ export type LastMessageStatus = | 'read' | 'viewed'; +export type SenderKeyDeviceType = { + id: number; + serviceId: ServiceIdString; + registrationId: number; +}; + export type SenderKeyInfoType = { createdAtDate: number; distributionId: string; - memberDevices: Array; + memberDevices: Array; }; export type CustomError = Error & { - identifier?: string; + serviceId?: ServiceIdString; number?: string; data?: object; retryAfter?: number; @@ -64,7 +65,7 @@ export type CustomError = Error & { export type GroupMigrationType = { areWeInvited: boolean; droppedMemberIds: Array; - invitedMembers: Array; + invitedMembers: Array; }; export type QuotedAttachment = { @@ -81,7 +82,7 @@ export type QuotedMessageType = { // `author` is an old attribute that holds the author's E164. We shouldn't use it for // new messages, but old messages might have this attribute. author?: string; - authorUuid?: string; + authorAci?: AciString; bodyRanges?: ReadonlyArray; id: number; isGiftBadge?: boolean; @@ -93,17 +94,10 @@ export type QuotedMessageType = { type StoryReplyContextType = { attachment?: AttachmentType; - authorUuid?: string; + authorAci?: AciString; messageId: string; }; -export type RetryOptions = Readonly<{ - type: 'session-reset'; - uuid: string; - e164: string; - now: number; -}>; - export type GroupV1Update = { avatarUpdated?: boolean; joined?: Array; @@ -114,25 +108,27 @@ export type GroupV1Update = { export type MessageReactionType = { emoji: undefined | string; fromId: string; - targetAuthorUuid: string; targetTimestamp: number; timestamp: number; isSentByConversationId?: Record; }; +// Note: when adding to the set of things that can change via edits, sendNormalMessage.ts +// needs more usage of get/setPropForTimestamp. export type EditHistoryType = { attachments?: Array; body?: string; bodyRanges?: ReadonlyArray; preview?: Array; quote?: QuotedMessageType; + sendStateByConversationId?: SendStateByConversationId; timestamp: number; }; export type MessageAttributesType = { bodyAttachment?: AttachmentType; bodyRanges?: ReadonlyArray; - callHistoryDetails?: CallHistoryDetailsFromDiskType; + callId?: string; canReplyToStory?: boolean; changedId?: string; dataMessage?: Uint8Array | null; @@ -163,9 +159,8 @@ export type MessageAttributesType = { quote?: QuotedMessageType; reactions?: ReadonlyArray; requiredProtocolVersion?: number; - retryOptions?: RetryOptions; sourceDevice?: number; - storyDistributionListId?: string; + storyDistributionListId?: StoryDistributionIdString; storyId?: string; storyReplyContext?: StoryReplyContextType; storyRecipientsVersion?: number; @@ -188,6 +183,7 @@ export type MessageAttributesType = { | 'incoming' | 'keychange' | 'outgoing' + | 'phone-number-discovery' | 'profile-change' | 'story' | 'timer-notification' @@ -204,7 +200,7 @@ export type MessageAttributesType = { conversationId: string; storyReaction?: { emoji: string; - targetAuthorUuid: string; + targetAuthorAci: AciString; targetTimestamp: number; }; giftBadge?: { @@ -219,7 +215,10 @@ export type MessageAttributesType = { expireTimer?: DurationInSeconds; fromSync?: unknown; source?: string; - sourceUuid?: string; + sourceServiceId?: ServiceIdString; + }; + phoneNumberDiscovery?: { + e164: string; }; conversationMerge?: { renderInfo: ConversationRenderInfoType; @@ -243,12 +242,12 @@ export type MessageAttributesType = { serverGuid?: string; serverTimestamp?: number; source?: string; - sourceUuid?: UUIDStringType; + sourceServiceId?: ServiceIdString; timestamp: number; // Backwards-compatibility with prerelease data schema - invitedGV2Members?: Array; + invitedGV2Members?: Array; droppedGV2MemberIds?: Array; sendHQImages?: boolean; @@ -277,7 +276,7 @@ export type ConversationLastProfileType = Readonly<{ export type ValidateConversationType = Pick< ConversationAttributesType, - 'e164' | 'uuid' | 'type' | 'groupId' + 'e164' | 'serviceId' | 'type' | 'groupId' >; export type DraftEditMessageType = { @@ -313,7 +312,6 @@ export type ConversationAttributesType = { draftBodyRanges?: DraftBodyRanges; draftTimestamp?: number | null; hideStory?: boolean; - hiddenFromConversationSearch?: boolean; inbox_position?: number; // When contact is removed - it is initially placed into `justNotification` // removal stage. In this stage user can still send messages (which will @@ -334,10 +332,7 @@ export type ConversationAttributesType = { messageRequestResponseType?: number; muteExpiresAt?: number; dontNotifyForMentionsIfMuted?: boolean; - profileAvatar?: null | { - hash: string; - path: string; - }; + profileAvatar?: ContactAvatarType | null; profileKeyCredential?: string | null; profileKeyCredentialExpiration?: number | null; lastProfile?: ConversationLastProfileType; @@ -372,8 +367,8 @@ export type ConversationAttributesType = { version: number; // Private core info - uuid?: UUIDStringType; - pni?: UUIDStringType; + serviceId?: ServiceIdString; + pni?: PniString; e164?: string; // Private other fields @@ -418,11 +413,7 @@ export type ConversationAttributesType = { addFromInviteLink: AccessRequiredEnum; }; announcementsOnly?: boolean; - avatar?: { - url: string; - path: string; - hash?: string; - } | null; + avatar?: ContactAvatarType | null; avatars?: Array; description?: string; expireTimer?: DurationInSeconds; @@ -464,7 +455,7 @@ export type ConversationRenderInfoType = Pick< >; export type GroupV2MemberType = { - uuid: UUIDStringType; + aci: AciString; role: MemberRoleEnum; joinedAtVersion: number; @@ -475,20 +466,27 @@ export type GroupV2MemberType = { approvedByAdmin?: boolean; }; +export type LegacyMigrationPendingMemberType = { + addedByUserId?: string; + uuid: string; + timestamp: number; + role: MemberRoleEnum; +}; + export type GroupV2PendingMemberType = { - addedByUserId?: UUIDStringType; - uuid: UUIDStringType; + addedByUserId?: AciString; + serviceId: ServiceIdString; timestamp: number; role: MemberRoleEnum; }; export type GroupV2BannedMemberType = { - uuid: UUIDStringType; + serviceId: ServiceIdString; timestamp: number; }; export type GroupV2PendingAdminApprovalType = { - uuid: UUIDStringType; + aci: AciString; timestamp: number; }; @@ -500,18 +498,3 @@ export type ShallowChallengeError = CustomError & { export declare class ConversationModelCollectionType extends Backbone.Collection { resetLookups(): void; } - -export declare class MessageModelCollectionType extends Backbone.Collection {} - -export type ReactionAttributesType = { - emoji: string; - fromId: string; - remove?: boolean; - source: ReactionSource; - // Necessary to put 1:1 story replies into the right conversation - not the same - // conversation as the target message! - storyReactionMessage?: MessageModel; - targetAuthorUuid: string; - targetTimestamp: number; - timestamp: number; -}; diff --git a/ts/models/conversations.ts b/ts/models/conversations.ts index ecef557627..1a6f7b0d09 100644 --- a/ts/models/conversations.ts +++ b/ts/models/conversations.ts @@ -19,7 +19,6 @@ import { getConversation } from '../util/getConversation'; import { drop } from '../util/drop'; import { isShallowEqual } from '../util/isShallowEqual'; import { getInitials } from '../util/getInitials'; -import { normalizeUuid } from '../util/normalizeUuid'; import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary'; import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; import type { AttachmentType, ThumbnailType } from '../types/Attachment'; @@ -30,8 +29,6 @@ import { getAboutText } from '../util/getAboutText'; import { getAvatarPath } from '../util/avatarUtils'; import { getDraftPreview } from '../util/getDraftPreview'; import { hasDraft } from '../util/hasDraft'; -import type { CallHistoryDetailsType } from '../types/Calling'; -import { CallMode } from '../types/Calling'; import * as Conversation from '../types/Conversation'; import type { StickerType, StickerWithHydratedData } from '../types/Stickers'; import * as Stickers from '../types/Stickers'; @@ -55,7 +52,7 @@ import type { } from '../types/Colors'; import type { MessageModel } from './messages'; import { getContact } from '../messages/helpers'; -import { assertDev, strictAssert } from '../util/assert'; +import { strictAssert } from '../util/assert'; import { isConversationMuted } from '../util/isConversationMuted'; import { isConversationSMSOnly } from '../util/isConversationSMSOnly'; import { @@ -63,14 +60,17 @@ import { isConversationUnregistered, isConversationUnregisteredAndStale, } from '../util/isConversationUnregistered'; -import { missingCaseError } from '../util/missingCaseError'; import { sniffImageMimeType } from '../util/sniffImageMimeType'; import { isValidE164 } from '../util/isValidE164'; -import { canConversationBeUnarchived } from '../util/canConversationBeUnarchived'; import type { MIMEType } from '../types/MIME'; import { IMAGE_JPEG, IMAGE_WEBP } from '../types/MIME'; -import { UUID, UUIDKind } from '../types/UUID'; -import type { UUIDStringType } from '../types/UUID'; +import type { AciString, PniString, ServiceIdString } from '../types/ServiceId'; +import { + ServiceIdKind, + normalizeServiceId, + normalizePni, +} from '../types/ServiceId'; +import { isAciString } from '../util/isAciString'; import { constantTimeEqual, decryptProfile, @@ -87,7 +87,6 @@ import { notificationService, } from '../services/notifications'; import { storageServiceUploadJob } from '../services/storage'; -import { scheduleOptimizeFTS } from '../services/ftsOptimizer'; import { getSendOptions } from '../util/getSendOptions'; import { isConversationAccepted } from '../util/isConversationAccepted'; import { @@ -129,7 +128,7 @@ import { conversationJobQueue, conversationQueueJobEnum, } from '../jobs/conversationJobQueue'; -import type { ReactionModel } from '../messageModifiers/Reactions'; +import type { ReactionAttributesType } from '../messageModifiers/Reactions'; import { isAnnouncementGroupReady } from '../util/isAnnouncementGroupReady'; import { getProfile } from '../util/getProfile'; import { SEALED_SENDER } from '../types/SealedSender'; @@ -160,8 +159,8 @@ import { ReceiptType } from '../types/Receipt'; import { getQuoteAttachment } from '../util/makeQuote'; import { deriveProfileKeyVersion } from '../util/zkgroup'; import { incrementMessageCounter } from '../util/incrementMessageCounter'; -import { validateTransition } from '../util/callHistoryDetails'; import OS from '../util/os/osMain'; +import { getMessageAuthorText } from '../util/getMessageAuthorText'; /* eslint-disable more/no-then */ window.Whisper = window.Whisper || {}; @@ -219,12 +218,16 @@ export class ConversationModel extends window.Backbone contactTypingTimers?: Record< string, - { senderId: string; timer: NodeJS.Timer } + { + senderId: string; + timer: NodeJS.Timer; + timestamp: number; + } >; contactCollection?: Backbone.Collection; - debouncedUpdateLastMessage?: (() => void) & { flush(): void }; + debouncedUpdateLastMessage: (() => void) & { flush(): void }; initialPromise?: Promise; @@ -256,8 +259,6 @@ export class ConversationModel extends window.Backbone throttledUpdateSharedGroups?: () => Promise; - private cachedLatestGroupCallEraId?: string; - private cachedIdenticon?: CachedIdenticon; public isFetchingUUID?: boolean; @@ -285,9 +286,7 @@ export class ConversationModel extends window.Backbone return getConversationIdForLogging(this.attributes); } - // This is one of the few times that we want to collapse our uuid/e164 pair down into - // just one bit of data. If we have a UUID, we'll send using it. - getSendTarget(): string | undefined { + getSendTarget(): ServiceIdString | undefined { return getSendTarget(this.attributes); } @@ -308,19 +307,20 @@ export class ConversationModel extends window.Backbone // Note that we intentionally don't use `initialize()` method because it // isn't compatible with esnext output of esbuild. - const uuid = this.get('uuid'); - const normalizedUuid = - uuid && normalizeUuid(uuid, 'ConversationModel.initialize'); - if (uuid && normalizedUuid !== uuid) { + const serviceId = this.getServiceId(); + const normalizedServiceId = + serviceId && + normalizeServiceId(serviceId, 'ConversationModel.initialize'); + if (serviceId && normalizedServiceId !== serviceId) { log.warn( - 'ConversationModel.initialize: normalizing uuid from ' + - `${uuid} to ${normalizedUuid}` + 'ConversationModel.initialize: normalizing serviceId from ' + + `${serviceId} to ${normalizedServiceId}` ); - this.set('uuid', normalizedUuid); + this.set('serviceId', normalizedServiceId); } if (isValidE164(attributes.id, false)) { - this.set({ id: UUID.generate().toString(), e164: attributes.id }); + this.set({ id: generateGuid(), e164: attributes.id }); } this.storeName = 'conversations'; @@ -361,14 +361,16 @@ export class ConversationModel extends window.Backbone if (sealedSender === undefined) { this.set({ sealedSender: SEALED_SENDER.UNKNOWN }); } + // @ts-expect-error -- Removing legacy prop this.unset('unidentifiedDelivery'); + // @ts-expect-error -- Removing legacy prop this.unset('unidentifiedDeliveryUnrestricted'); + // @ts-expect-error -- Removing legacy prop this.unset('hasFetchedProfile'); + // @ts-expect-error -- Removing legacy prop this.unset('tokens'); this.on('change:members change:membersV2', this.fetchContacts); - this.on('change:isArchived', this.onArchiveChange); - this.typingRefreshTimer = null; this.typingPauseTimer = null; @@ -440,7 +442,7 @@ export class ConversationModel extends window.Backbone return { getGroupId: () => this.get('groupId'), getMembers: () => this.getMembers(), - hasMember: (uuid: UUIDStringType) => this.hasMember(new UUID(uuid)), + hasMember: (serviceId: ServiceIdString) => this.hasMember(serviceId), idForLogging: () => this.idForLogging(), isGroupV2: () => isGroupV2(this.attributes), isValid: () => isGroupV2(this.attributes), @@ -458,20 +460,20 @@ export class ConversationModel extends window.Backbone return this.privVerifiedEnum; } - private isMemberRequestingToJoin(uuid: UUID): boolean { - return isMemberRequestingToJoin(this.attributes, uuid); + private isMemberRequestingToJoin(serviceId: ServiceIdString): boolean { + return isMemberRequestingToJoin(this.attributes, serviceId); } - isMemberPending(uuid: UUID): boolean { - return isMemberPending(this.attributes, uuid); + isMemberPending(serviceId: ServiceIdString): boolean { + return isMemberPending(this.attributes, serviceId); } - isMemberAwaitingApproval(uuid: UUID): boolean { - return isMemberAwaitingApproval(this.attributes, uuid); + isMemberAwaitingApproval(serviceId: ServiceIdString): boolean { + return isMemberAwaitingApproval(this.attributes, serviceId); } - isMember(uuid: UUID): boolean { - return isMember(this.attributes, uuid); + isMember(serviceId: ServiceIdString): boolean { + return isMember(this.attributes, serviceId); } async updateExpirationTimerInGroupV2( @@ -495,17 +497,17 @@ export class ConversationModel extends window.Backbone } private async promotePendingMember( - uuidKind: UUIDKind + serviceIdKind: ServiceIdKind ): Promise { const idLog = this.idForLogging(); const us = window.ConversationController.getOurConversationOrThrow(); - const uuid = window.storage.user.getCheckedUuid(uuidKind); + const serviceId = window.storage.user.getCheckedServiceId(serviceIdKind); // This user's pending state may have changed in the time between the user's // button press and when we get here. It's especially important to check here // in conflict/retry cases. - if (!this.isMemberPending(uuid)) { + if (!this.isMemberPending(serviceId)) { log.warn( `promotePendingMember/${idLog}: we are not a pending member of group. Returning early.` ); @@ -522,7 +524,7 @@ export class ConversationModel extends window.Backbone const profileKeyCredentialBase64 = us.get('profileKeyCredential'); strictAssert(profileKeyCredentialBase64, 'Must have profileKeyCredential'); - if (uuidKind === UUIDKind.ACI) { + if (serviceIdKind === ServiceIdKind.ACI) { return window.Signal.Groups.buildPromoteMemberChange({ group: this.attributes, isPendingPniAciProfileKey: false, @@ -531,7 +533,10 @@ export class ConversationModel extends window.Backbone }); } - strictAssert(uuidKind === UUIDKind.PNI, 'Must be a PNI promotion'); + strictAssert( + serviceIdKind === ServiceIdKind.PNI, + 'Must be a PNI promotion' + ); return window.Signal.Groups.buildPromoteMemberChange({ group: this.attributes, @@ -542,27 +547,27 @@ export class ConversationModel extends window.Backbone } private async denyPendingApprovalRequest( - uuid: UUID + aci: AciString ): Promise { const idLog = this.idForLogging(); // This user's pending state may have changed in the time between the user's // button press and when we get here. It's especially important to check here // in conflict/retry cases. - if (!this.isMemberRequestingToJoin(uuid)) { + if (!this.isMemberRequestingToJoin(aci)) { log.warn( - `denyPendingApprovalRequest/${idLog}: ${uuid} is not requesting ` + + `denyPendingApprovalRequest/${idLog}: ${aci} is not requesting ` + 'to join the group. Returning early.' ); return undefined; } - const ourUuid = window.textsecure.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.textsecure.storage.user.getCheckedAci(); return window.Signal.Groups.buildDeletePendingAdminApprovalMemberChange({ group: this.attributes, - ourUuid, - uuid, + ourAci, + aci, }); } @@ -582,7 +587,9 @@ export class ConversationModel extends window.Backbone ); } - const uuid = toRequest.getCheckedUuid(`addPendingApprovalRequest/${idLog}`); + const serviceId = toRequest.getCheckedServiceId( + `addPendingApprovalRequest/${idLog}` + ); // We need the user's profileKeyCredential, which requires a roundtrip with the // server, and most definitely their profileKey. A getProfiles() call will @@ -602,7 +609,7 @@ export class ConversationModel extends window.Backbone // This user's pending state may have changed in the time between the user's // button press and when we get here. It's especially important to check here // in conflict/retry cases. - if (this.isMemberAwaitingApproval(uuid)) { + if (this.isMemberAwaitingApproval(serviceId)) { log.warn( `addPendingApprovalRequest/${idLog}: ` + `${toRequest.idForLogging()} already in pending approval.` @@ -617,12 +624,16 @@ export class ConversationModel extends window.Backbone }); } - async addMember(uuid: UUID): Promise { + async addMember( + serviceId: ServiceIdString + ): Promise { const idLog = this.idForLogging(); - const toRequest = window.ConversationController.get(uuid.toString()); + const toRequest = window.ConversationController.get(serviceId); if (!toRequest) { - throw new Error(`addMember/${idLog}: No conversation found for ${uuid}`); + throw new Error( + `addMember/${idLog}: No conversation found for ${serviceId}` + ); } // We need the user's profileKeyCredential, which requires a roundtrip with the @@ -643,7 +654,7 @@ export class ConversationModel extends window.Backbone // This user's pending state may have changed in the time between the user's // button press and when we get here. It's especially important to check here // in conflict/retry cases. - if (this.isMember(uuid)) { + if (this.isMember(serviceId)) { log.warn( `addMember/${idLog}: ${toRequest.idForLogging()} ` + 'is already a member.' @@ -655,42 +666,42 @@ export class ConversationModel extends window.Backbone group: this.attributes, profileKeyCredentialBase64, serverPublicParamsBase64: window.getServerPublicParams(), - uuid, + serviceId, }); } private async removePendingMember( - uuids: ReadonlyArray + serviceIds: ReadonlyArray ): Promise { - return removePendingMember(this.attributes, uuids); + return removePendingMember(this.attributes, serviceIds); } private async removeMember( - uuid: UUID + serviceId: ServiceIdString ): Promise { const idLog = this.idForLogging(); // This user's pending state may have changed in the time between the user's // button press and when we get here. It's especially important to check here // in conflict/retry cases. - if (!this.isMember(uuid)) { + if (!this.isMember(serviceId)) { log.warn( - `removeMember/${idLog}: ${uuid} is not a pending member of group. Returning early.` + `removeMember/${idLog}: ${serviceId} is not a pending member of group. Returning early.` ); return undefined; } - const ourUuid = window.textsecure.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.textsecure.storage.user.getCheckedAci(); return window.Signal.Groups.buildDeleteMemberChange({ group: this.attributes, - ourUuid, - uuid, + ourAci, + serviceId, }); } private async toggleAdminChange( - uuid: UUID + serviceId: ServiceIdString ): Promise { if (!isGroupV2(this.attributes)) { return undefined; @@ -698,22 +709,22 @@ export class ConversationModel extends window.Backbone const idLog = this.idForLogging(); - if (!this.isMember(uuid)) { + if (!this.isMember(serviceId)) { log.warn( - `toggleAdminChange/${idLog}: ${uuid} is not a pending member of group. Returning early.` + `toggleAdminChange/${idLog}: ${serviceId} is not a pending member of group. Returning early.` ); return undefined; } const MEMBER_ROLES = Proto.Member.Role; - const role = this.isAdmin(uuid) + const role = this.isAdmin(serviceId) ? MEMBER_ROLES.DEFAULT : MEMBER_ROLES.ADMINISTRATOR; return window.Signal.Groups.buildModifyMemberRoleChange({ group: this.attributes, - uuid, + serviceId, role, }); } @@ -800,8 +811,8 @@ export class ConversationModel extends window.Backbone } const e164 = this.get('e164'); - const pni = this.get('pni'); - const aci = this.get('uuid'); + const pni = this.getPni(); + const aci = this.getServiceId(); if (e164 && pni && aci && pni !== aci) { this.updateE164(undefined); this.updatePni(undefined); @@ -873,9 +884,9 @@ export class ConversationModel extends window.Backbone let blocked = false; const wasBlocked = this.isBlocked(); - const uuid = this.get('uuid'); - if (uuid) { - drop(window.storage.blocked.addBlockedUuid(uuid)); + const serviceId = this.getServiceId(); + if (serviceId) { + drop(window.storage.blocked.addBlockedServiceId(serviceId)); blocked = true; } @@ -905,9 +916,9 @@ export class ConversationModel extends window.Backbone let unblocked = false; const wasBlocked = this.isBlocked(); - const uuid = this.get('uuid'); - if (uuid) { - drop(window.storage.blocked.removeBlockedUuid(uuid)); + const serviceId = this.getServiceId(); + if (serviceId) { + drop(window.storage.blocked.removeBlockedServiceId(serviceId)); unblocked = true; } @@ -972,10 +983,10 @@ export class ConversationModel extends window.Backbone }); window.reduxActions?.stories.removeAllContactStories(this.id); - const uuid = this.get('uuid'); - if (uuid) { + const serviceId = this.getServiceId(); + if (serviceId) { window.reduxActions?.storyDistributionLists.removeMemberFromAllDistributionLists( - uuid + serviceId ); } @@ -1157,7 +1168,7 @@ export class ConversationModel extends window.Backbone ); } - if (!this.get('uuid')) { + if (!this.getServiceId()) { return; } @@ -1217,7 +1228,7 @@ export class ConversationModel extends window.Backbone includePendingMembers?: boolean; extraConversationsForSend?: ReadonlyArray; } - | { members: ReadonlyArray } + | { members: ReadonlyArray } ) > = {} ): GroupV2InfoType | undefined { @@ -1348,12 +1359,12 @@ export class ConversationModel extends window.Backbone } async onNewMessage(message: MessageModel): Promise { - const uuid = message.get('sourceUuid'); + const serviceId = message.get('sourceServiceId'); const e164 = message.get('source'); const sourceDevice = message.get('sourceDevice'); const source = window.ConversationController.lookupOrCreate({ - uuid, + serviceId, e164, reason: 'ConversationModel.onNewMessage', }); @@ -1395,9 +1406,7 @@ export class ConversationModel extends window.Backbone ): Promise { await this.beforeAddSingleMessage(message); this.doAddSingleMessage(message, { isJustSent }); - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.debouncedUpdateLastMessage!(); + this.debouncedUpdateLastMessage(); } private async beforeAddSingleMessage(message: MessageModel): Promise { @@ -1433,7 +1442,10 @@ export class ConversationModel extends window.Backbone newestId && messageIds && messageIds[messageIds.length - 1] === newestId; if (isJustSent && existingConversation && !isLatestInMemory) { - void this.loadNewestMessages(undefined, undefined); + // The message is being sent before the user has scrolled down to load the newest + // messages into memory; in that case, we scroll the user all the way down by + // loading the newest message + drop(this.loadNewestMessages(newestId, undefined)); } else if ( // The message has to be not a story or has to be a story reply in direct // conversation. @@ -1756,13 +1768,19 @@ export class ConversationModel extends window.Backbone ): Promise> { const result = messages .filter(message => Boolean(message.id)) - .map(message => window.MessageController.register(message.id, message)); + .map(message => + window.MessageCache.__DEPRECATED$register( + message.id, + message, + 'cleanModels' + ) + ); const eliminated = messages.length - result.length; if (eliminated > 0) { log.warn(`cleanModels: Eliminated ${eliminated} messages without an id`); } - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); + const ourAci = window.textsecure.storage.user.getCheckedAci(); let upgraded = 0; for (let max = result.length, i = 0; i < max; i += 1) { @@ -1776,7 +1794,7 @@ export class ConversationModel extends window.Backbone const upgradedMessage = await upgradeMessageSchema(attributes); message.set(upgradedMessage); // eslint-disable-next-line no-await-in-loop - await window.Signal.Data.saveMessage(upgradedMessage, { ourUuid }); + await window.Signal.Data.saveMessage(upgradedMessage, { ourAci }); upgraded += 1; } } @@ -1850,28 +1868,29 @@ export class ConversationModel extends window.Backbone this.captureChange('updateE164'); } - updateUuid(uuid?: string): void { - const oldValue = this.get('uuid'); - if (uuid === oldValue) { + updateServiceId(serviceId?: ServiceIdString): void { + const oldValue = this.getServiceId(); + if (serviceId === oldValue) { return; } - this.set('uuid', uuid ? UUID.cast(uuid.toLowerCase()) : undefined); + this.set( + 'serviceId', + serviceId + ? normalizeServiceId(serviceId, 'Conversation.updateServiceId') + : undefined + ); window.Signal.Data.updateConversation(this.attributes); - this.trigger('idUpdated', this, 'uuid', oldValue); + this.trigger('idUpdated', this, 'serviceId', oldValue); // We should delete the old sessions and identity information in all situations except // for the case where we need to do old and new PNI comparisons. We'll wait // for the PNI update to do that. - if (oldValue && oldValue !== this.get('pni')) { - drop( - window.textsecure.storage.protocol.removeIdentityKey( - UUID.cast(oldValue) - ) - ); + if (oldValue && oldValue !== this.getPni()) { + drop(window.textsecure.storage.protocol.removeIdentityKey(oldValue)); } - this.captureChange('updateUuid'); + this.captureChange('updateServiceId'); } trackPreviousIdentityKey(publicKey: Uint8Array): void { @@ -1897,18 +1916,21 @@ export class ConversationModel extends window.Backbone window.Signal.Data.updateConversation(this.attributes); } - updatePni(pni?: string): void { - const oldValue = this.get('pni'); + updatePni(pni?: PniString): void { + const oldValue = this.getPni(); if (pni === oldValue) { return; } - this.set('pni', pni ? UUID.cast(pni.toLowerCase()) : undefined); + this.set( + 'pni', + pni ? normalizePni(pni, 'Conversation.updatePni') : undefined + ); const pniIsPrimaryId = - !this.get('uuid') || - this.get('uuid') === oldValue || - this.get('uuid') === pni; + !this.getServiceId() || + this.getServiceId() === oldValue || + this.getServiceId() === pni; const haveSentMessage = Boolean( this.get('profileSharing') || this.get('sentMessageCount') ); @@ -1917,13 +1939,9 @@ export class ConversationModel extends window.Backbone // We're going from an old PNI to a new PNI if (pni) { const oldIdentityRecord = - window.textsecure.storage.protocol.getIdentityRecord( - UUID.cast(oldValue) - ); + window.textsecure.storage.protocol.getIdentityRecord(oldValue); const newIdentityRecord = - window.textsecure.storage.protocol.getIdentityRecord( - UUID.checkedLookup(pni) - ); + window.textsecure.storage.protocol.getIdentityRecord(pni); if ( newIdentityRecord && @@ -1942,9 +1960,7 @@ export class ConversationModel extends window.Backbone // We're just dropping the PNI if (!pni) { const oldIdentityRecord = - window.textsecure.storage.protocol.getIdentityRecord( - UUID.cast(oldValue) - ); + window.textsecure.storage.protocol.getIdentityRecord(oldValue); if (oldIdentityRecord) { this.trackPreviousIdentityKey(oldIdentityRecord.publicKey); @@ -1954,16 +1970,12 @@ export class ConversationModel extends window.Backbone // If this PNI is going away or going to someone else, we'll delete all its sessions if (oldValue) { - drop( - window.textsecure.storage.protocol.removeIdentityKey( - UUID.cast(oldValue) - ) - ); + drop(window.textsecure.storage.protocol.removeIdentityKey(oldValue)); } - if (pni && !this.get('uuid')) { + if (pni && !this.getServiceId()) { log.warn( - `updatePni/${this.idForLogging()}: pni field set to ${pni}, but uuid field is empty!` + `updatePni/${this.idForLogging()}: pni field set to ${pni}, but service id field is empty!` ); } @@ -2025,7 +2037,7 @@ export class ConversationModel extends window.Backbone options: { isLocalAction?: boolean } = {} ): Promise { const { isLocalAction } = options; - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); + const ourAci = window.textsecure.storage.user.getCheckedAci(); let messages: Array | undefined; do { @@ -2056,25 +2068,34 @@ export class ConversationModel extends window.Backbone type: conversationQueueJobEnum.enum.Receipts, conversationId: this.get('id'), receiptsType: ReceiptType.Read, - receipts: readMessages.map(m => ({ - messageId: m.id, - conversationId, - senderE164: m.source, - senderUuid: m.sourceUuid, - timestamp: getMessageSentTimestamp(m, { log }), - isDirectConversation: isDirectConversation(this.attributes), - })), + receipts: readMessages.map(m => { + const { sourceServiceId: senderAci } = m; + strictAssert(isAciString(senderAci), "Can't send receipt to PNI"); + + return { + messageId: m.id, + conversationId, + senderE164: m.source, + senderAci, + timestamp: getMessageSentTimestamp(m, { log }), + isDirectConversation: isDirectConversation(this.attributes), + }; + }), }); } // eslint-disable-next-line no-await-in-loop await Promise.all( readMessages.map(async m => { - const registered = window.MessageController.register(m.id, m); + const registered = window.MessageCache.__DEPRECATED$register( + m.id, + m, + 'handleReadAndDownloadAttachments' + ); const shouldSave = await registered.queueAttachmentDownloads(); if (shouldSave) { await window.Signal.Data.saveMessage(registered.attributes, { - ourUuid, + ourAci, }); } }) @@ -2113,10 +2134,8 @@ export class ConversationModel extends window.Backbone } if (isLocalAction) { - const ourACI = window.textsecure.storage.user.getCheckedUuid( - UUIDKind.ACI - ); - const ourPNI = window.textsecure.storage.user.getUuid(UUIDKind.PNI); + const ourAci = window.textsecure.storage.user.getCheckedAci(); + const ourPni = window.textsecure.storage.user.getPni(); const ourConversation = window.ConversationController.getOurConversationOrThrow(); @@ -2127,24 +2146,26 @@ export class ConversationModel extends window.Backbone void this.sendProfileKeyUpdate(); } else if ( isGroupV2(this.attributes) && - this.isMemberPending(ourACI) + this.isMemberPending(ourAci) ) { await this.modifyGroupV2({ name: 'promotePendingMember', usingCredentialsFrom: [ourConversation], - createGroupChange: () => this.promotePendingMember(UUIDKind.ACI), + createGroupChange: () => + this.promotePendingMember(ServiceIdKind.ACI), }); } else if ( - ourPNI && + ourPni && isGroupV2(this.attributes) && - this.isMemberPending(ourPNI) + this.isMemberPending(ourPni) ) { await this.modifyGroupV2({ name: 'promotePendingMember', usingCredentialsFrom: [ourConversation], - createGroupChange: () => this.promotePendingMember(UUIDKind.PNI), + createGroupChange: () => + this.promotePendingMember(ServiceIdKind.PNI), }); - } else if (isGroupV2(this.attributes) && this.isMember(ourACI)) { + } else if (isGroupV2(this.attributes) && this.isMember(ourAci)) { log.info( 'applyMessageRequestResponse/accept: Already a member of v2 group' ); @@ -2234,7 +2255,7 @@ export class ConversationModel extends window.Backbone inviteLinkPassword: string; approvalRequired: boolean; }): Promise { - const ourACI = window.textsecure.storage.user.getCheckedUuid(); + const ourAci = window.textsecure.storage.user.getCheckedAci(); const ourConversation = window.ConversationController.getOurConversationOrThrow(); try { @@ -2250,7 +2271,7 @@ export class ConversationModel extends window.Backbone name: 'joinGroup', usingCredentialsFrom: [ourConversation], inviteLinkPassword, - createGroupChange: () => this.addMember(ourACI), + createGroupChange: () => this.addMember(ourAci), }); } } catch (error) { @@ -2269,7 +2290,7 @@ export class ConversationModel extends window.Backbone this.set({ pendingAdminApprovalV2: [ { - uuid: ourACI.toString(), + aci: ourAci, timestamp: Date.now(), }, ], @@ -2290,7 +2311,7 @@ export class ConversationModel extends window.Backbone } async cancelJoinRequest(): Promise { - const ourACI = window.storage.user.getCheckedUuid(UUIDKind.ACI); + const ourAci = window.storage.user.getCheckedAci(); const inviteLinkPassword = this.get('groupInviteLinkPassword'); if (!inviteLinkPassword) { @@ -2303,7 +2324,7 @@ export class ConversationModel extends window.Backbone name: 'cancelJoinRequest', usingCredentialsFrom: [], inviteLinkPassword, - createGroupChange: () => this.denyPendingApprovalRequest(ourACI), + createGroupChange: () => this.denyPendingApprovalRequest(ourAci), }); } @@ -2312,29 +2333,29 @@ export class ConversationModel extends window.Backbone return; } - const ourACI = window.textsecure.storage.user.getCheckedUuid(UUIDKind.ACI); - const ourPNI = window.textsecure.storage.user.getUuid(UUIDKind.PNI); + const ourAci = window.textsecure.storage.user.getCheckedAci(); + const ourPni = window.textsecure.storage.user.getPni(); const ourConversation = window.ConversationController.getOurConversationOrThrow(); - if (this.isMemberPending(ourACI)) { + if (this.isMemberPending(ourAci)) { await this.modifyGroupV2({ name: 'delete', usingCredentialsFrom: [], - createGroupChange: () => this.removePendingMember([ourACI]), + createGroupChange: () => this.removePendingMember([ourAci]), }); - } else if (this.isMember(ourACI)) { + } else if (this.isMember(ourAci)) { await this.modifyGroupV2({ name: 'delete', usingCredentialsFrom: [ourConversation], - createGroupChange: () => this.removeMember(ourACI), + createGroupChange: () => this.removeMember(ourAci), }); // Keep PNI in pending if ACI was a member. - } else if (ourPNI && this.isMemberPending(ourPNI)) { + } else if (ourPni && this.isMemberPending(ourPni)) { await this.modifyGroupV2({ name: 'delete', usingCredentialsFrom: [], - createGroupChange: () => this.removePendingMember([ourPNI]), + createGroupChange: () => this.removePendingMember([ourPni]), syncMessageOnly: true, }); } else { @@ -2347,21 +2368,21 @@ export class ConversationModel extends window.Backbone } async addBannedMember( - uuid: UUID + serviceId: ServiceIdString ): Promise { - if (this.isMember(uuid)) { + if (this.isMember(serviceId)) { log.warn('addBannedMember: Member is a part of the group!'); return; } - if (this.isMemberPending(uuid)) { + if (this.isMemberPending(serviceId)) { log.warn('addBannedMember: Member is pending to be added to group!'); return; } - if (isMemberBanned(this.attributes, uuid)) { + if (isMemberBanned(this.attributes, serviceId)) { log.warn('addBannedMember: Member is already banned!'); return; @@ -2369,15 +2390,15 @@ export class ConversationModel extends window.Backbone return window.Signal.Groups.buildAddBannedMemberChange({ group: this.attributes, - uuid, + serviceId, }); } - async blockGroupLinkRequests(uuid: UUIDStringType): Promise { + async blockGroupLinkRequests(serviceId: ServiceIdString): Promise { await this.modifyGroupV2({ name: 'addBannedMember', usingCredentialsFrom: [], - createGroupChange: async () => this.addBannedMember(new UUID(uuid)), + createGroupChange: async () => this.addBannedMember(serviceId), }); } @@ -2394,9 +2415,9 @@ export class ConversationModel extends window.Backbone return; } - const uuid = member.getCheckedUuid(`toggleAdmin/${logId}`); + const serviceId = member.getCheckedServiceId(`toggleAdmin/${logId}`); - if (!this.isMember(uuid)) { + if (!this.isMember(serviceId)) { log.error( `toggleAdmin: Member ${conversationId} is not a member of the group` ); @@ -2406,7 +2427,7 @@ export class ConversationModel extends window.Backbone await this.modifyGroupV2({ name: 'toggleAdmin', usingCredentialsFrom: [member], - createGroupChange: () => this.toggleAdminChange(uuid), + createGroupChange: () => this.toggleAdminChange(serviceId), }); } @@ -2423,27 +2444,30 @@ export class ConversationModel extends window.Backbone ); } - const uuid = pendingMember.getCheckedUuid(`removeFromGroupV2/${logId}`); + const serviceId = pendingMember.getCheckedServiceId( + `removeFromGroupV2/${logId}` + ); - if (this.isMemberRequestingToJoin(uuid)) { + if (this.isMemberRequestingToJoin(serviceId)) { + strictAssert(isAciString(serviceId), 'Requesting member is not ACI'); await this.modifyGroupV2({ name: 'denyPendingApprovalRequest', usingCredentialsFrom: [], - createGroupChange: () => this.denyPendingApprovalRequest(uuid), + createGroupChange: () => this.denyPendingApprovalRequest(serviceId), extraConversationsForSend: [conversationId], }); - } else if (this.isMemberPending(uuid)) { + } else if (this.isMemberPending(serviceId)) { await this.modifyGroupV2({ name: 'removePendingMember', usingCredentialsFrom: [], - createGroupChange: () => this.removePendingMember([uuid]), + createGroupChange: () => this.removePendingMember([serviceId]), extraConversationsForSend: [conversationId], }); - } else if (this.isMember(uuid)) { + } else if (this.isMember(serviceId)) { await this.modifyGroupV2({ name: 'removeFromGroup', usingCredentialsFrom: [pendingMember], - createGroupChange: () => this.removeMember(uuid), + createGroupChange: () => this.removeMember(serviceId), extraConversationsForSend: [conversationId], }); } else { @@ -2474,7 +2498,7 @@ export class ConversationModel extends window.Backbone await singleProtoJobQueue.add( MessageSender.getMessageRequestResponseSync({ threadE164: this.get('e164'), - threadUuid: this.get('uuid'), + threadAci: this.getAci(), groupId, type: response, }) @@ -2488,13 +2512,13 @@ export class ConversationModel extends window.Backbone } async safeGetVerified(): Promise { - const uuid = this.getUuid(); - if (!uuid) { + const serviceId = this.getServiceId(); + if (!serviceId) { return this.verifiedEnum.DEFAULT; } try { - return await window.textsecure.storage.protocol.getVerified(uuid); + return await window.textsecure.storage.protocol.getVerified(serviceId); } catch { return this.verifiedEnum.DEFAULT; } @@ -2554,20 +2578,20 @@ export class ConversationModel extends window.Backbone ); } - const uuid = this.getUuid(); + const aci = this.getAci(); const beginningVerified = this.get('verified') ?? DEFAULT; const keyChange = false; - if (uuid) { + if (aci) { if (verified === this.verifiedEnum.DEFAULT) { - await window.textsecure.storage.protocol.setVerified(uuid, verified); + await window.textsecure.storage.protocol.setVerified(aci, verified); } else { - await window.textsecure.storage.protocol.setVerified(uuid, verified, { + await window.textsecure.storage.protocol.setVerified(aci, verified, { firstUse: false, nonblockingApproval: true, }); } } else { - log.warn(`_setVerified(${this.id}): no uuid to update protocol storage`); + log.warn(`_setVerified(${this.id}): no aci to update protocol storage`); } this.set({ verified }); @@ -2595,8 +2619,8 @@ export class ConversationModel extends window.Backbone local: isExplicitUserAction, }); } - if (isExplicitUserAction && uuid) { - await this.sendVerifySyncMessage(this.get('e164'), uuid, verified); + if (isExplicitUserAction && aci) { + await this.sendVerifySyncMessage(this.get('e164'), aci, verified); } return keyChange; @@ -2604,16 +2628,9 @@ export class ConversationModel extends window.Backbone async sendVerifySyncMessage( e164: string | undefined, - uuid: UUID, + aci: AciString, state: number ): Promise { - const identifier = uuid ? uuid.toString() : e164; - if (!identifier) { - throw new Error( - 'sendVerifySyncMessage: Neither e164 nor UUID were provided' - ); - } - if (window.ConversationController.areWePrimaryDevice()) { log.warn( 'sendVerifySyncMessage: We are primary device; not sending sync' @@ -2621,18 +2638,16 @@ export class ConversationModel extends window.Backbone return; } - const key = await window.textsecure.storage.protocol.loadIdentityKey( - UUID.checkedLookup(identifier) - ); + const key = await window.textsecure.storage.protocol.loadIdentityKey(aci); if (!key) { throw new Error( - `sendVerifySyncMessage: No identity key found for identifier ${identifier}` + `sendVerifySyncMessage: No identity key found for aci ${aci}` ); } try { await singleProtoJobQueue.add( - MessageSender.getVerificationSync(e164, uuid.toString(), state, key) + MessageSender.getVerificationSync(e164, aci, state, key) ); } catch (error) { log.error( @@ -2702,23 +2717,23 @@ export class ConversationModel extends window.Backbone ); } - const uuid = this.getUuid(); - if (!uuid) { - log.warn(`setApproved(${this.id}): no uuid, ignoring`); + const serviceId = this.getServiceId(); + if (!serviceId) { + log.warn(`setApproved(${this.id}): no serviceId, ignoring`); return; } return this.queueJob('setApproved', async () => { - return window.textsecure.storage.protocol.setApproval(uuid, true); + return window.textsecure.storage.protocol.setApproval(serviceId, true); }); } safeIsUntrusted(timestampThreshold?: number): boolean { try { - const uuid = this.getUuid(); - strictAssert(uuid, `No uuid for conversation: ${this.id}`); + const serviceId = this.getServiceId(); + strictAssert(serviceId, `No serviceId for conversation: ${this.id}`); return window.textsecure.storage.protocol.isUntrusted( - uuid, + serviceId, timestampThreshold ); } catch (err) { @@ -2820,14 +2835,15 @@ export class ConversationModel extends window.Backbone } as unknown as MessageAttributesType; const id = await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( id, new window.Whisper.Message({ ...message, id, - }) + }), + 'addChatSessionRefreshed' ); this.trigger('newmessage', model); @@ -2837,23 +2853,23 @@ export class ConversationModel extends window.Backbone async addDeliveryIssue({ receivedAt, receivedAtCounter, - senderUuid, + senderAci, sentAt, }: { receivedAt: number; receivedAtCounter: number; - senderUuid: string; + senderAci: AciString; sentAt: number; }): Promise { log.info(`addDeliveryIssue: adding for ${this.idForLogging()}`, { sentAt, - senderUuid, + senderAci, }); const message = { conversationId: this.id, type: 'delivery-issue', - sourceUuid: senderUuid, + sourceServiceId: senderAci, sent_at: receivedAt, received_at: receivedAtCounter, received_at_ms: receivedAt, @@ -2864,14 +2880,15 @@ export class ConversationModel extends window.Backbone } as unknown as MessageAttributesType; const id = await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( id, new window.Whisper.Message({ ...message, id, - }) + }), + 'addDeliveryIssue' ); this.trigger('newmessage', model); @@ -2880,14 +2897,16 @@ export class ConversationModel extends window.Backbone void this.updateUnread(); } - async addKeyChange(reason: string, keyChangedId?: UUID): Promise { - const keyChangedIdString = keyChangedId?.toString(); - return this.queueJob(`addKeyChange(${keyChangedIdString})`, async () => { + async addKeyChange( + reason: string, + keyChangedId?: ServiceIdString + ): Promise { + return this.queueJob(`addKeyChange(${keyChangedId})`, async () => { log.info( 'adding key change advisory in', this.idForLogging(), 'for', - keyChangedIdString || 'this conversation', + keyChangedId || 'this conversation', this.get('timestamp'), 'reason:', reason @@ -2908,43 +2927,43 @@ export class ConversationModel extends window.Backbone timestamp, received_at: incrementMessageCounter(), received_at_ms: timestamp, - key_changed: keyChangedIdString, + key_changed: keyChangedId, readStatus: ReadStatus.Read, seenStatus: SeenStatus.Unseen, schemaVersion: Message.VERSION_NEEDED_FOR_DISPLAY, }; await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), forceSave: true, }); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( message.id, - new window.Whisper.Message(message) + new window.Whisper.Message(message), + 'addKeyChange' ); const isUntrusted = await this.isUntrusted(); this.trigger('newmessage', model); - const uuid = this.get('uuid'); - // Group calls are always with folks that have a UUID - if (isUntrusted && uuid) { - window.reduxActions.calling.keyChanged({ uuid }); + const serviceId = this.getServiceId(); + // Group calls are always with folks that have a serviceId + if (isUntrusted && isAciString(serviceId)) { + window.reduxActions.calling.keyChanged({ aci: serviceId }); } if (isDirectConversation(this.attributes)) { window.reduxActions?.safetyNumber.clearSafetyNumber(this.id); } - if (isDirectConversation(this.attributes) && uuid) { - const parsedUuid = UUID.checkedLookup(uuid); + if (isDirectConversation(this.attributes) && serviceId) { const groups = - await window.ConversationController.getAllGroupsInvolvingUuid( - parsedUuid + await window.ConversationController.getAllGroupsInvolvingServiceId( + serviceId ); groups.forEach(group => { - void group.addKeyChange('addKeyChange - group fan-out', parsedUuid); + void group.addKeyChange('addKeyChange - group fan-out', serviceId); }); } @@ -2954,8 +2973,8 @@ export class ConversationModel extends window.Backbone const updatedSenderKeyInfo = { ...senderKeyInfo, memberDevices: senderKeyInfo.memberDevices.filter( - ({ identifier }) => { - return identifier !== keyChangedIdString; + ({ serviceId: memberServiceId }) => { + return memberServiceId !== keyChangedId; } ), }; @@ -2995,15 +3014,69 @@ export class ConversationModel extends window.Backbone }; const id = await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), forceSave: true, }); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( id, new window.Whisper.Message({ ...message, id, - }) + }), + 'addConversationMerge' + ); + + this.trigger('newmessage', model); + } + + async addPhoneNumberDiscoveryIfNeeded(originalPni: PniString): Promise { + const logId = `addPhoneNumberDiscoveryIfNeeded(${this.idForLogging()}, ${originalPni})`; + + const e164 = this.get('e164'); + + if (!e164) { + log.info(`${logId}: not adding, no e164`); + return; + } + + const hadSession = await window.textsecure.storage.protocol.hasSessionWith( + originalPni + ); + + if (!hadSession) { + log.info(`${logId}: not adding, no PNI session`); + return; + } + + log.info(`${logId}: adding notification`); + const timestamp = Date.now(); + const message: MessageAttributesType = { + id: generateGuid(), + conversationId: this.id, + type: 'phone-number-discovery', + sent_at: timestamp, + timestamp, + received_at: incrementMessageCounter(), + received_at_ms: timestamp, + phoneNumberDiscovery: { + e164, + }, + readStatus: ReadStatus.Read, + seenStatus: SeenStatus.Unseen, + schemaVersion: Message.VERSION_NEEDED_FOR_DISPLAY, + }; + + const id = await window.Signal.Data.saveMessage(message, { + ourAci: window.textsecure.storage.user.getCheckedAci(), + forceSave: true, + }); + const model = window.MessageCache.__DEPRECATED$register( + id, + new window.Whisper.Message({ + ...message, + id, + }), + 'addPhoneNumberDiscoveryIfNeeded' ); this.trigger('newmessage', model); @@ -3046,202 +3119,28 @@ export class ConversationModel extends window.Backbone }; await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), forceSave: true, }); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( message.id, - new window.Whisper.Message(message) + new window.Whisper.Message(message), + 'addVerifiedChange' ); this.trigger('newmessage', model); void this.updateUnread(); - const uuid = this.getUuid(); - if (isDirectConversation(this.attributes) && uuid) { - void window.ConversationController.getAllGroupsInvolvingUuid(uuid).then( - groups => { - groups.forEach(group => { - void group.addVerifiedChange(this.id, verified, options); - }); - } - ); - } - } - - async addCallHistory( - callHistoryDetails: CallHistoryDetailsType, - receivedAtCounter: number | undefined - ): Promise { - let timestamp: number; - let unread: boolean; - let detailsToSave: CallHistoryDetailsType; - - switch (callHistoryDetails.callMode) { - case CallMode.Direct: { - const { - callId, - wasIncoming, - wasVideoCall, - wasDeclined, - acceptedTime, - endedTime, - } = callHistoryDetails; - log.info( - `addCallHistory: Conversation ID: ${this.id}, ` + - `Call ID: ${callId}, ` + - 'Direct, ' + - `Incoming: ${wasIncoming}, ` + - `Video: ${wasVideoCall}, ` + - `Declined: ${wasDeclined}, ` + - `Accepted: ${acceptedTime}, ` + - `Ended: ${endedTime}` - ); - - const resolvedTime = acceptedTime ?? endedTime; - assertDev(resolvedTime, 'Direct call must have accepted or ended time'); - timestamp = resolvedTime; - unread = - callHistoryDetails.wasIncoming && - !callHistoryDetails.wasDeclined && - !callHistoryDetails.acceptedTime; - detailsToSave = { - ...callHistoryDetails, - callMode: CallMode.Direct, - }; - break; - } - case CallMode.Group: - timestamp = callHistoryDetails.startedTime; - unread = false; - detailsToSave = callHistoryDetails; - break; - default: - throw missingCaseError(callHistoryDetails); - } - // This is sometimes called inside of another conversation queue job so if - // awaited it would block on this forever. - drop( - this.queueJob('addCallHistory', async () => { - // Force save if we're adding a new call history message for a direct call - let forceSave = true; - let previousMessage: MessageAttributesType | null = null; - if (callHistoryDetails.callMode === CallMode.Direct) { - const messageId = - await window.Signal.Data.getCallHistoryMessageByCallId( - this.id, - callHistoryDetails.callId - ); - if (messageId != null) { - log.info( - `addCallHistory: Found existing call history message (Call ID: ${callHistoryDetails.callId}, Message ID: ${messageId})` - ); - // We don't want to force save if we're updating an existing message - forceSave = false; - previousMessage = - (await window.Signal.Data.getMessageById(messageId)) ?? null; - } else { - log.info( - `addCallHistory: No existing call history message found (Call ID: ${callHistoryDetails.callId})` - ); - } - } - - if ( - !validateTransition( - previousMessage?.callHistoryDetails, - callHistoryDetails, - log - ) - ) { - log.info("addCallHistory: Transition isn't valid, not saving"); - return; - } - - const message: MessageAttributesType = { - id: previousMessage?.id ?? generateGuid(), - conversationId: this.id, - type: 'call-history', - sent_at: timestamp, - timestamp, - received_at: receivedAtCounter || incrementMessageCounter(), - received_at_ms: timestamp, - readStatus: unread ? ReadStatus.Unread : ReadStatus.Read, - seenStatus: unread ? SeenStatus.Unseen : SeenStatus.NotApplicable, - callHistoryDetails, - }; - - const id = await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), - forceSave, + const serviceId = this.getServiceId(); + if (isDirectConversation(this.attributes) && serviceId) { + void window.ConversationController.getAllGroupsInvolvingServiceId( + serviceId + ).then(groups => { + groups.forEach(group => { + void group.addVerifiedChange(this.id, verified, options); }); - - log.info(`addCallHistory: Saved call history message (ID: ${id})`); - - const model = window.MessageController.register( - id, - new window.Whisper.Message({ - ...message, - id, - }) - ); - - if ( - detailsToSave.callMode === CallMode.Direct && - !detailsToSave.wasIncoming - ) { - this.incrementSentMessageCount(); - } else { - this.incrementMessageCount(); - } - - this.trigger('newmessage', model); - - void this.updateUnread(); - this.set('active_at', timestamp); - - if (canConversationBeUnarchived(this.attributes)) { - this.setArchived(false); - } else { - window.Signal.Data.updateConversation(this.attributes); - } - }) - ); - } - - /** - * Adds a group call history message if one is needed. It won't add history messages for - * the same group call era ID. - * - * Resolves with `true` if a new message was added, and `false` otherwise. - */ - async updateCallHistoryForGroupCall( - eraId: string, - creatorUuid: string - ): Promise { - // We want to update the cache quickly in case this function is called multiple times. - const oldCachedEraId = this.cachedLatestGroupCallEraId; - this.cachedLatestGroupCallEraId = eraId; - - const alreadyHasMessage = - (oldCachedEraId && oldCachedEraId === eraId) || - (await window.Signal.Data.hasGroupCallHistoryMessage(this.id, eraId)); - - if (alreadyHasMessage) { - void this.updateLastMessage(); - return false; + }); } - - await this.addCallHistory( - { - callMode: CallMode.Group, - creatorUuid, - eraId, - startedTime: Date.now(), - }, - undefined - ); - return true; } async addProfileChange( @@ -3263,27 +3162,28 @@ export class ConversationModel extends window.Backbone } as unknown as MessageAttributesType; const id = await window.Signal.Data.saveMessage(message, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( id, new window.Whisper.Message({ ...message, id, - }) + }), + 'addProfileChange' ); this.trigger('newmessage', model); - const uuid = this.getUuid(); - if (isDirectConversation(this.attributes) && uuid) { - void window.ConversationController.getAllGroupsInvolvingUuid(uuid).then( - groups => { - groups.forEach(group => { - void group.addProfileChange(profileChange, this.id); - }); - } - ); + const serviceId = this.getServiceId(); + if (isDirectConversation(this.attributes) && serviceId) { + void window.ConversationController.getAllGroupsInvolvingServiceId( + serviceId + ).then(groups => { + groups.forEach(group => { + void group.addProfileChange(profileChange, this.id); + }); + }); } } @@ -3308,15 +3208,16 @@ export class ConversationModel extends window.Backbone // TODO: DESKTOP-722 message as MessageAttributesType, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), } ); - const model = window.MessageController.register( + const model = window.MessageCache.__DEPRECATED$register( id, new window.Whisper.Message({ ...(message as MessageAttributesType), id, - }) + }), + 'addNotification' ); this.trigger('newmessage', model); @@ -3396,7 +3297,7 @@ export class ConversationModel extends window.Backbone `maybeRemoveUniversalTimer(${this.idForLogging()}): removed notification` ); - const message = window.MessageController.getById(notificationId); + const message = window.MessageCache.__DEPRECATED$getById(notificationId); if (message) { await window.Signal.Data.removeMessage(message.id); } @@ -3433,7 +3334,7 @@ export class ConversationModel extends window.Backbone `maybeClearContactRemoved(${this.idForLogging()}): removed notification` ); - const message = window.MessageController.getById(notificationId); + const message = window.MessageCache.__DEPRECATED$getById(notificationId); if (message) { await window.Signal.Data.removeMessage(message.id); } @@ -3445,12 +3346,15 @@ export class ConversationModel extends window.Backbone oldValue: string, newValue: string ): Promise { - const sourceUuid = this.getCheckedUuid( - 'Change number notification without uuid' + const sourceServiceId = this.getCheckedServiceId( + 'Change number notification without service id' ); const { storage } = window.textsecure; - if (storage.user.getOurUuidKind(sourceUuid) !== UUIDKind.Unknown) { + if ( + storage.user.getOurServiceIdKind(sourceServiceId) !== + ServiceIdKind.Unknown + ) { log.info( `Conversation ${this.idForLogging()}: not adding change number ` + 'notification for ourselves' @@ -3460,13 +3364,13 @@ export class ConversationModel extends window.Backbone log.info( `Conversation ${this.idForLogging()}: adding change number ` + - `notification for ${sourceUuid.toString()} from ${oldValue} to ${newValue}` + `notification for ${sourceServiceId} from ${oldValue} to ${newValue}` ); const convos = [ this, - ...(await window.ConversationController.getAllGroupsInvolvingUuid( - sourceUuid + ...(await window.ConversationController.getAllGroupsInvolvingServiceId( + sourceServiceId )), ]; @@ -3475,13 +3379,17 @@ export class ConversationModel extends window.Backbone return convo.addNotification('change-number-notification', { readStatus: ReadStatus.Read, seenStatus: SeenStatus.Unseen, - sourceUuid: sourceUuid.toString(), + sourceServiceId, }); }) ); } - async onReadMessage(message: MessageModel, readAt?: number): Promise { + async onReadMessage( + message: MessageModel, + readAt?: number, + newestSentAt?: number + ): Promise { // We mark as read everything older than this message - to clean up old stuff // still marked unread in the database. If the user generally doesn't read in // the desktop app, so the desktop app only gets read syncs, we can very @@ -3496,7 +3404,7 @@ export class ConversationModel extends window.Backbone return this.queueJob('onReadMessage', () => // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.markRead(message.get('received_at')!, { - newestSentAt: message.get('sent_at'), + newestSentAt: newestSentAt || message.get('sent_at'), sendReadReceipts: false, readAt, }) @@ -3549,13 +3457,13 @@ export class ConversationModel extends window.Backbone }); } - isAdmin(uuid: UUID): boolean { + isAdmin(serviceId: ServiceIdString): boolean { if (!isGroupV2(this.attributes)) { return false; } const members = this.get('membersV2') || []; - const member = members.find(x => x.uuid === uuid.toString()); + const member = members.find(x => x.aci === serviceId); if (!member) { return false; } @@ -3565,23 +3473,32 @@ export class ConversationModel extends window.Backbone return member.role === MEMBER_ROLES.ADMINISTRATOR; } - getUuid(): UUID | undefined { - try { - const value = this.get('uuid'); - return value ? new UUID(value) : undefined; - } catch (err) { - log.warn( - `getUuid(): failed to obtain conversation(${this.id}) uuid due to`, - Errors.toLogFormat(err) - ); - return undefined; - } + getServiceId(): ServiceIdString | undefined { + return this.get('serviceId'); } - getCheckedUuid(reason: string): UUID { - const result = this.getUuid(); - strictAssert(result !== undefined, reason); - return result; + getCheckedServiceId(reason: string): ServiceIdString { + const serviceId = this.getServiceId(); + strictAssert(serviceId !== undefined, reason); + return serviceId; + } + + getAci(): AciString | undefined { + const value = this.getServiceId(); + if (value && isAciString(value)) { + return value; + } + return undefined; + } + + getCheckedAci(reason: string): AciString { + const aci = this.getAci(); + strictAssert(aci !== undefined, reason); + return aci; + } + + getPni(): PniString | undefined { + return this.get('pni'); } getGroupLink(): string | undefined { @@ -3623,13 +3540,6 @@ export class ConversationModel extends window.Backbone return members.map(member => member.id); } - getMemberUuids(): Array { - const members = this.getMembers(); - return members.map(member => { - return member.getCheckedUuid('Group member without uuid'); - }); - } - getRecipients({ includePendingMembers, extraConversationsForSend, @@ -3637,7 +3547,7 @@ export class ConversationModel extends window.Backbone includePendingMembers?: boolean; extraConversationsForSend?: ReadonlyArray; isStoryReply?: boolean; - } = {}): Array { + } = {}): Array { return getRecipients(this.attributes, { includePendingMembers, extraConversationsForSend, @@ -3806,7 +3716,7 @@ export class ConversationModel extends window.Backbone draftBodyRanges: [], draftTimestamp: null, quotedMessageId: undefined, - lastMessageAuthor: message.getAuthorText(), + lastMessageAuthor: getMessageAuthorText(message.attributes), lastMessageBodyRanges: message.get('bodyRanges'), lastMessage: notificationData?.text || message.getNotificationText() || '', @@ -3897,7 +3807,6 @@ export class ConversationModel extends window.Backbone if (!storyId || isDirectConversation(this.attributes)) { await this.maybeApplyUniversalTimer(); expireTimer = this.get('expireTimer'); - await this.restoreContact(); } const recipientMaybeConversations = map( @@ -3929,7 +3838,7 @@ export class ConversationModel extends window.Backbone // Here we move attachments to disk const attributes = await upgradeMessageSchema({ - id: UUID.generate().toString(), + id: generateGuid(), timestamp: now, type: 'outgoing', body, @@ -3959,7 +3868,11 @@ export class ConversationModel extends window.Backbone }); const model = new window.Whisper.Message(attributes); - const message = window.MessageController.register(model.id, model); + const message = window.MessageCache.__DEPRECATED$register( + model.id, + model, + 'enqueueMessageForSend' + ); message.cachedOutgoingContactData = contact; // Attach path to preview images so that sendNormalMessage can use them to @@ -4003,7 +3916,7 @@ export class ConversationModel extends window.Backbone await window.Signal.Data.saveMessage(message.attributes, { jobToInsert, forceSave: true, - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } ); @@ -4033,6 +3946,12 @@ export class ConversationModel extends window.Backbone extraReduxActions, }); + // The call above enables profile sharing so we have to restore contact + // afterwards, otherwise Message Request state will flash. + if (!storyId || isDirectConversation(this.attributes)) { + await this.restoreContact(); + } + const renderDuration = Date.now() - renderStart; if (renderDuration > SEND_REPORTING_THRESHOLD_MS) { @@ -4127,11 +4046,9 @@ export class ConversationModel extends window.Backbone const conversationId = this.id; - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); const stats = await window.Signal.Data.getConversationMessageStats({ conversationId, includeStoryReplies: !isGroup(this.attributes), - ourUuid, }); // This runs as a job to avoid race conditions @@ -4145,17 +4062,22 @@ export class ConversationModel extends window.Backbone let previewMessage: MessageModel | undefined; let activityMessage: MessageModel | undefined; - // Register the message with MessageController so that if it already exists + // Register the message with MessageCache so that if it already exists // in memory we use that data instead of the data from the db which may // be out of date. if (preview) { - previewMessage = window.MessageController.register(preview.id, preview); + previewMessage = window.MessageCache.__DEPRECATED$register( + preview.id, + preview, + 'previewMessage' + ); } if (activity) { - activityMessage = window.MessageController.register( + activityMessage = window.MessageCache.__DEPRECATED$register( activity.id, - activity + activity, + 'activityMessage' ); } @@ -4187,7 +4109,7 @@ export class ConversationModel extends window.Backbone notificationData?.text || previewMessage?.getNotificationText() || '', lastMessageBodyRanges: notificationData?.bodyRanges, lastMessagePrefix: notificationData?.emoji, - lastMessageAuthor: previewMessage?.getAuthorText(), + lastMessageAuthor: getMessageAuthorText(previewMessage?.attributes), lastMessageStatus: (previewMessage ? getMessagePropStatus(previewMessage.attributes, ourConversationId) @@ -4217,17 +4139,6 @@ export class ConversationModel extends window.Backbone } } - private onArchiveChange() { - const isArchived = this.get('isArchived'); - if (isArchived) { - return; - } - if (!this.get('hiddenFromConversationSearch')) { - return; - } - this.set('hiddenFromConversationSearch', false); - } - setMarkedUnread(markedUnread: boolean): void { const previousMarkedUnread = this.get('markedUnread'); @@ -4549,12 +4460,16 @@ export class ConversationModel extends window.Backbone } as unknown as MessageAttributesType); const id = await window.Signal.Data.saveMessage(model.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); model.set({ id }); - const message = window.MessageController.register(id, model); + const message = window.MessageCache.__DEPRECATED$register( + id, + model, + 'updateExpirationTimer' + ); void this.addSingleMessage(message); void this.updateUnread(); @@ -4608,6 +4523,7 @@ export class ConversationModel extends window.Backbone unreadMentionsCount, }); window.Signal.Data.updateConversation(this.attributes); + window.reduxActions.callHistory.updateCallHistoryUnreadCount(); } } @@ -4621,16 +4537,18 @@ export class ConversationModel extends window.Backbone return; } - const ourUuid = window.textsecure.storage.user.getCheckedUuid(); - const theirUuid = this.getUuid(); - if (!theirUuid) { + const ourAci = window.textsecure.storage.user.getCheckedAci(); + const theirAci = this.getAci(); + if (!theirAci) { return; } const ourGroups = - await window.ConversationController.getAllGroupsInvolvingUuid(ourUuid); + await window.ConversationController.getAllGroupsInvolvingServiceId( + ourAci + ); const sharedGroups = ourGroups - .filter(c => c.hasMember(ourUuid) && c.hasMember(theirUuid)) + .filter(c => c.hasMember(ourAci) && c.hasMember(theirAci)) .sort( (left, right) => (right.get('timestamp') || 0) - (left.get('timestamp') || 0) @@ -4656,7 +4574,7 @@ export class ConversationModel extends window.Backbone await Promise.all( conversations.map(conversation => - getProfile(conversation.get('uuid'), conversation.get('e164')) + getProfile(conversation.getServiceId(), conversation.get('e164')) ) ); } @@ -4728,8 +4646,8 @@ export class ConversationModel extends window.Backbone if (decrypted) { const newAttributes = await Conversation.maybeUpdateProfileAvatar( this.attributes, - decrypted, { + data: decrypted, writeNewAttachmentData, deleteAttachmentData, doesAttachmentExist, @@ -4826,8 +4744,8 @@ export class ConversationModel extends window.Backbone return; } - const uuid = this.get('uuid'); - if (!uuid) { + const serviceId = this.getServiceId(); + if (!serviceId) { return; } @@ -4836,7 +4754,7 @@ export class ConversationModel extends window.Backbone return lastProfile.profileKeyVersion; } - const profileKeyVersion = deriveProfileKeyVersion(profileKey, uuid); + const profileKeyVersion = deriveProfileKeyVersion(profileKey, serviceId); if (!profileKeyVersion) { log.warn( 'deriveProfileKeyVersion: Failed to derive profile key version, ' + @@ -4903,10 +4821,10 @@ export class ConversationModel extends window.Backbone await window.Signal.Data.updateConversation(this.attributes); } - hasMember(uuid: UUID): boolean { + hasMember(serviceId: ServiceIdString): boolean { const members = this.getMembers(); - return members.some(member => member.get('uuid') === uuid.toString()); + return members.some(member => member.getServiceId() === serviceId); } fetchContacts(): void { @@ -4924,16 +4842,11 @@ export class ConversationModel extends window.Backbone active_at: null, pendingUniversalTimer: undefined, }); - if (isGroup(this.attributes)) { - this.set('hiddenFromConversationSearch', true); - } window.Signal.Data.updateConversation(this.attributes); await window.Signal.Data.removeAllMessagesInConversation(this.id, { logId: this.idForLogging(), }); - - scheduleOptimizeFTS(); } getTitle(options?: { isShort?: boolean }): string { @@ -4991,7 +4904,7 @@ export class ConversationModel extends window.Backbone } // Set of items to captureChanges on: - // [-] uuid + // [-] serviceId // [-] e164 // [X] profileKey // [-] identityKey @@ -5070,7 +4983,7 @@ export class ConversationModel extends window.Backbone async notify( message: Readonly, - reaction?: Readonly + reaction?: Readonly ): Promise { // As a performance optimization don't perform any work if notifications are // disabled. @@ -5083,23 +4996,16 @@ export class ConversationModel extends window.Backbone return; } - const ourACI = window.textsecure.storage.user.getCheckedUuid( - UUIDKind.ACI - ); - const ourPNI = window.textsecure.storage.user.getCheckedUuid( - UUIDKind.PNI - ); - const ourUuids: Set = new Set([ - ourACI.toString(), - ourPNI.toString(), - ]); + const ourAci = window.textsecure.storage.user.getCheckedAci(); + const ourPni = window.textsecure.storage.user.getCheckedPni(); + const ourServiceIds: Set = new Set([ourAci, ourPni]); const mentionsMe = (message.get('bodyRanges') || []).some(bodyRange => { if (!BodyRange.isMention(bodyRange)) { return false; } - return ourUuids.has( - normalizeUuid(bodyRange.mentionUuid, 'notify: mentionsMe check') + return ourServiceIds.has( + normalizeServiceId(bodyRange.mentionAci, 'notify: mentionsMe check') ); }); if (!mentionsMe) { @@ -5115,7 +5021,7 @@ export class ConversationModel extends window.Backbone const isMessageInDirectConversation = isDirectConversation(this.attributes); const sender = reaction - ? window.ConversationController.get(reaction.get('fromId')) + ? window.ConversationController.get(reaction.fromId) : getContact(message.attributes); const senderName = sender ? sender.getTitle() @@ -5144,7 +5050,13 @@ export class ConversationModel extends window.Backbone isExpiringMessage, message: message.getNotificationText(), messageId, - reaction: reaction ? reaction.toJSON() : null, + reaction: reaction + ? { + emoji: reaction.emoji, + targetAuthorAci: reaction.targetAuthorAci, + targetTimestamp: reaction.targetTimestamp, + } + : undefined, sentAt: message.get('timestamp'), type: reaction ? NotificationType.Reaction : NotificationType.Message, }); @@ -5239,14 +5151,14 @@ export class ConversationModel extends window.Backbone return; } - const senderUuid = sender.getUuid(); - if (!senderUuid) { + const senderServiceId = sender.getServiceId(); + if (!senderServiceId) { return; } // Drop typing indicators for announcement only groups where the sender // is not an admin - if (this.get('announcementsOnly') && !this.isAdmin(senderUuid)) { + if (this.get('announcementsOnly') && !this.isAdmin(senderServiceId)) { return; } @@ -5272,8 +5184,8 @@ export class ConversationModel extends window.Backbone this.clearContactTypingTimer.bind(this, typingToken), 15 * 1000 ); + // User was not previously typing before. State change! if (!record) { - // User was not previously typing before. State change! this.trigger('change', this, { force: true }); } } else { @@ -5392,7 +5304,7 @@ export class ConversationModel extends window.Backbone async flushDebouncedUpdates(): Promise { try { - await this.debouncedUpdateLastMessage?.flush(); + this.debouncedUpdateLastMessage.flush(); } catch (error) { const logId = this.idForLogging(); log.error( @@ -5461,7 +5373,7 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ /** * window.Backbone defines a `_byId` field. Here we set up additional `_byE164`, - * `_byUuid`, and `_byGroupId` fields so we can track conversations by more + * `_byServiceId`, and `_byGroupId` fields so we can track conversations by more * than just their id. */ initialize() { @@ -5474,8 +5386,8 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ if (idProp === 'e164') { delete this._byE164[oldValue]; } - if (idProp === 'uuid') { - delete this._byUuid[oldValue]; + if (idProp === 'serviceId') { + delete this._byServiceId[oldValue]; } if (idProp === 'pni') { delete this._byPni[oldValue]; @@ -5488,11 +5400,11 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ if (e164) { this._byE164[e164] = model; } - const uuid = model.get('uuid'); - if (uuid) { - this._byUuid[uuid] = model; + const serviceId = model.getServiceId(); + if (serviceId) { + this._byServiceId[serviceId] = model; } - const pni = model.get('pni'); + const pni = model.getPni(); if (pni) { this._byPni[pni] = model; } @@ -5520,28 +5432,28 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ if (e164) { const existing = this._byE164[e164]; - // Prefer the contact with both e164 and uuid - if (!existing || (existing && !existing.get('uuid'))) { + // Prefer the contact with both e164 and serviceId + if (!existing || (existing && !existing.getServiceId())) { this._byE164[e164] = model; } } - const uuid = model.get('uuid'); - if (uuid) { - const existing = this._byUuid[uuid]; + const serviceId = model.getServiceId(); + if (serviceId) { + const existing = this._byServiceId[serviceId]; - // Prefer the contact with both e164 and uuid + // Prefer the contact with both e164 and seviceId if (!existing || (existing && !existing.get('e164'))) { - this._byUuid[uuid] = model; + this._byServiceId[serviceId] = model; } } - const pni = model.get('pni'); + const pni = model.getPni(); if (pni) { const existing = this._byPni[pni]; - // Prefer the contact with both uuid and pni - if (!existing || (existing && !existing.get('uuid'))) { + // Prefer the contact with both serviceId and pni + if (!existing || (existing && !existing.getServiceId())) { this._byPni[pni] = model; } } @@ -5555,7 +5467,7 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ eraseLookups() { this._byE164 = Object.create(null); - this._byUuid = Object.create(null); + this._byServiceId = Object.create(null); this._byPni = Object.create(null); this._byGroupId = Object.create(null); }, @@ -5607,7 +5519,7 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ /** * window.Backbone collections have a `_byId` field that `get` defers to. Here, we - * override `get` to first access our custom `_byE164`, `_byUuid`, and + * override `get` to first access our custom `_byE164`, `_byServiceId`, and * `_byGroupId` functions, followed by falling back to the original * window.Backbone implementation. */ @@ -5615,7 +5527,7 @@ window.Whisper.ConversationCollection = window.Backbone.Collection.extend({ return ( this._byE164[id] || this._byE164[`+${id}`] || - this._byUuid[id] || + this._byServiceId[id] || this._byPni[id] || this._byGroupId[id] || window.Backbone.Collection.prototype.get.call(this, id) diff --git a/ts/models/messages.ts b/ts/models/messages.ts index e57fdb9dd6..742e3f1c66 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -13,6 +13,8 @@ import { pick, union, } from 'lodash'; +import { v4 as generateUuid } from 'uuid'; + import type { CustomError, MessageAttributesType, @@ -25,11 +27,10 @@ import type { DeleteAttributesType } from '../messageModifiers/Deletes'; import type { SentEventData } from '../textsecure/messageReceiverEvents'; import { isNotNil } from '../util/isNotNil'; import { isNormalNumber } from '../util/isNormalNumber'; -import { softAssert, strictAssert } from '../util/assert'; +import { strictAssert } from '../util/assert'; +import { hydrateStoryContext } from '../util/hydrateStoryContext'; import { drop } from '../util/drop'; -import { dropNull } from '../util/dropNull'; import type { ConversationModel } from './conversations'; -import { getCallingNotificationText } from '../util/callingNotification'; import type { ProcessedDataMessage, ProcessedQuote, @@ -37,23 +38,19 @@ import type { CallbackResultType, } from '../textsecure/Types.d'; import { SendMessageProtoError } from '../textsecure/Errors'; -import * as expirationTimer from '../util/expirationTimer'; import { getUserLanguages } from '../util/userLanguages'; -import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; -import { getTaggedConversationUuid } from '../util/getConversationUuid'; +import { copyCdnFields } from '../util/attachments'; import type { ReactionType } from '../types/Reactions'; -import { UUID, UUIDKind } from '../types/UUID'; +import type { ServiceIdString } from '../types/ServiceId'; +import { normalizeServiceId } from '../types/ServiceId'; +import { isAciString } from '../util/isAciString'; import * as reactionUtil from '../reactions/util'; -import * as Stickers from '../types/Stickers'; import * as Errors from '../types/errors'; -import * as EmbeddedContact from '../types/EmbeddedContact'; import type { AttachmentType } from '../types/Attachment'; import { isImage, isVideo } from '../types/Attachment'; -import * as Attachment from '../types/Attachment'; import { stringToMIMEType } from '../types/MIME'; import * as MIME from '../types/MIME'; -import * as GroupChange from '../groupChange'; import { ReadStatus } from '../messages/MessageReadStatus'; import type { SendStateByConversationId } from '../messages/MessageSendState'; import { @@ -67,7 +64,6 @@ import { migrateLegacyReadStatus } from '../messages/migrateLegacyReadStatus'; import { migrateLegacySendAttributes } from '../messages/migrateLegacySendAttributes'; import { getOwn } from '../util/getOwn'; import { markRead, markViewed } from '../services/MessageUpdater'; -import { scheduleOptimizeFTS } from '../services/ftsOptimizer'; import { isDirectConversation, isGroup, @@ -76,12 +72,9 @@ import { } from '../util/whatTypeOfConversation'; import { handleMessageSend } from '../util/handleMessageSend'; import { getSendOptions } from '../util/getSendOptions'; -import { findAndFormatContact } from '../util/findAndFormatContact'; import { modifyTargetMessage } from '../util/modifyTargetMessage'; import { - getAttachmentsForMessage, getMessagePropStatus, - getPropsForCallHistory, hasErrors, isCallHistory, isChatSessionRefreshed, @@ -103,14 +96,10 @@ import { isUnsupportedMessage, isVerifiedChange, isConversationMerge, - extractHydratedMentions, + isPhoneNumberDiscovery, } from '../state/selectors/message'; -import { - isInCall, - getCallSelector, - getActiveCall, -} from '../state/selectors/calling'; -import type { ReactionModel } from '../messageModifiers/Reactions'; +import type { ReactionAttributesType } from '../messageModifiers/Reactions'; +import { isInCall } from '../state/selectors/calling'; import { ReactionSource } from '../reactions/ReactionSource'; import * as LinkPreview from '../types/LinkPreview'; import { SignalService as Proto } from '../protobuf'; @@ -131,47 +120,43 @@ import { cleanupMessage, deleteMessageData } from '../util/cleanup'; import { getContact, getSource, - getSourceUuid, + getSourceServiceId, isCustomError, messageHasPaymentEvent, isQuoteAMatch, - getPaymentEventNotificationText, } from '../messages/helpers'; -import type { ReplacementValuesType } from '../types/I18N'; import { viewOnceOpenJobQueue } from '../jobs/viewOnceOpenJobQueue'; import { getMessageIdForLogging } from '../util/idForLogging'; import { hasAttachmentDownloads } from '../util/hasAttachmentDownloads'; import { queueAttachmentDownloads } from '../util/queueAttachmentDownloads'; import { findStoryMessages } from '../util/findStoryMessage'; -import { getStoryDataFromMessageAttributes } from '../services/storyLoader'; import type { ConversationQueueJobData } from '../jobs/conversationJobQueue'; -import { getMessageById } from '../messages/getMessageById'; import { shouldDownloadStory } from '../util/shouldDownloadStory'; -import { shouldShowStoriesView } from '../state/selectors/stories'; import type { EmbeddedContactWithHydratedAvatar } from '../types/EmbeddedContact'; import { SeenStatus } from '../MessageSeenStatus'; import { isNewReactionReplacingPrevious } from '../reactions/util'; import { parseBoostBadgeListFromServer } from '../badges/parseBadgesFromServer'; -import { GiftBadgeStates } from '../components/conversation/Message'; import type { StickerWithHydratedData } from '../types/Stickers'; -import { getStringForConversationMerge } from '../util/getStringForConversationMerge'; + import { addToAttachmentDownloadQueue, shouldUseAttachmentDownloadQueue, } from '../util/attachmentDownloadQueue'; -import { getTitleNoDefault, getNumber } from '../util/getTitle'; import dataInterface from '../sql/Client'; import { getQuoteBodyText } from '../util/getQuoteBodyText'; import { shouldReplyNotifyUser } from '../util/shouldReplyNotifyUser'; -import { isConversationAccepted } from '../util/isConversationAccepted'; import type { RawBodyRange } from '../types/BodyRange'; -import { BodyRange, applyRangesForText } from '../types/BodyRange'; -import { getStringForProfileChange } from '../util/getStringForProfileChange'; +import { BodyRange } from '../types/BodyRange'; import { queueUpdateMessage, saveNewMessageBatcher, } from '../util/messageBatcher'; -import { normalizeUuid } from '../util/normalizeUuid'; +import { getSenderIdentifier } from '../util/getSenderIdentifier'; +import { getNotificationDataForMessage } from '../util/getNotificationDataForMessage'; +import { getNotificationTextForMessage } from '../util/getNotificationTextForMessage'; +import { getMessageAuthorText } from '../util/getMessageAuthorText'; +import { getPropForTimestamp, setPropForTimestamp } from '../util/editHelpers'; +import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; /* eslint-disable more/no-then */ @@ -209,9 +194,17 @@ export class MessageModel extends window.Backbone.Model { cachedOutgoingStickerData?: StickerWithHydratedData; + public registerLocations: Set; + constructor(attributes: MessageAttributesType) { super(attributes); + if (!this.id && attributes.id) { + this.id = attributes.id; + } + + this.registerLocations = new Set(); + // Note that we intentionally don't use `initialize()` method because it // isn't compatible with esnext output of esbuild. if (isObject(attributes)) { @@ -255,54 +248,19 @@ export class MessageModel extends window.Backbone.Model { this.CURRENT_PROTOCOL_VERSION = Proto.DataMessage.ProtocolVersion.CURRENT; this.INITIAL_PROTOCOL_VERSION = Proto.DataMessage.ProtocolVersion.INITIAL; - this.on('change', this.notifyRedux); + this.on('change', this.updateMessageCache); } - notifyRedux(): void { - if (!window.reduxActions) { - return; - } - - const { storyChanged } = window.reduxActions.stories; - - if (isStory(this.attributes)) { - const storyData = getStoryDataFromMessageAttributes({ - ...this.attributes, - }); - - if (!storyData) { - return; - } - - storyChanged(storyData); - - // We don't want messageChanged to run - return; - } - - const { messageChanged } = window.reduxActions.conversations; - - if (messageChanged) { - const conversationId = this.get('conversationId'); - // Note: The clone is important for triggering a re-run of selectors - messageChanged(this.id, conversationId, { ...this.attributes }); - } + updateMessageCache(): void { + window.MessageCache.setAttributes({ + messageId: this.id, + messageAttributes: this.attributes, + skipSaveToDatabase: true, + }); } getSenderIdentifier(): string { - const sentAt = this.get('sent_at'); - const source = this.get('source'); - const sourceUuid = this.get('sourceUuid'); - const sourceDevice = this.get('sourceDevice'); - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const conversation = window.ConversationController.lookupOrCreate({ - e164: source, - uuid: sourceUuid, - reason: 'MessageModel.getSenderIdentifier', - })!; - - return `${conversation?.id}.${sourceDevice}-${sentAt}`; + return getSenderIdentifier(this.attributes); } getReceivedAt(): number { @@ -327,6 +285,7 @@ export class MessageModel extends window.Backbone.Model { !isGroupV1Migration(attributes) && !isGroupV2Change(attributes) && !isKeyChange(attributes) && + !isPhoneNumberDiscovery(attributes) && !isProfileChange(attributes) && !isUniversalTimerNotification(attributes) && !isUnsupportedMessage(attributes) && @@ -342,61 +301,7 @@ export class MessageModel extends window.Backbone.Model { shouldSave?: boolean; } = {} ): Promise { - const ourUuid = window.textsecure.storage.user.getCheckedUuid().toString(); - const storyId = this.get('storyId'); - if (!storyId) { - return; - } - - const context = this.get('storyReplyContext'); - // We'll continue trying to get the attachment as long as the message still exists - if (context && (context.attachment?.url || !context.messageId)) { - return; - } - - const message = - inMemoryMessage === undefined - ? (await getMessageById(storyId))?.attributes - : inMemoryMessage; - - if (!message) { - const conversation = this.getConversation(); - softAssert( - conversation && isDirectConversation(conversation.attributes), - 'hydrateStoryContext: Not a type=direct conversation' - ); - this.set({ - storyReplyContext: { - attachment: undefined, - // This is ok to do because story replies only show in 1:1 conversations - // so the story that was quoted should be from the same conversation. - authorUuid: conversation?.get('uuid'), - // No messageId, referenced story not found! - messageId: '', - }, - }); - if (shouldSave) { - await window.Signal.Data.saveMessage(this.attributes, { ourUuid }); - } - return; - } - - const attachments = getAttachmentsForMessage({ ...message }); - let attachment: AttachmentType | undefined = attachments?.[0]; - if (attachment && !attachment.url && !attachment.textAttachment) { - attachment = undefined; - } - - this.set({ - storyReplyContext: { - attachment, - authorUuid: message.sourceUuid, - messageId: message.id, - }, - }); - if (shouldSave) { - await window.Signal.Data.saveMessage(this.attributes, { ourUuid }); - } + await hydrateStoryContext(this.id, inMemoryMessage, { shouldSave }); } // Dependencies of prop-generation functions @@ -409,485 +314,11 @@ export class MessageModel extends window.Backbone.Model { text: string; bodyRanges?: ReadonlyArray; } { - // eslint-disable-next-line prefer-destructuring - const attributes: MessageAttributesType = this.attributes; - - if (isDeliveryIssue(attributes)) { - return { - emoji: '⚠', - text: window.i18n('icu:DeliveryIssue--preview'), - }; - } - - if (isConversationMerge(attributes)) { - const conversation = this.getConversation(); - strictAssert( - conversation, - 'getNotificationData/isConversationMerge/conversation' - ); - strictAssert( - attributes.conversationMerge, - 'getNotificationData/isConversationMerge/conversationMerge' - ); - - return { - text: getStringForConversationMerge({ - obsoleteConversationTitle: getTitleNoDefault( - attributes.conversationMerge.renderInfo - ), - obsoleteConversationNumber: getNumber( - attributes.conversationMerge.renderInfo - ), - conversationTitle: conversation.getTitle(), - i18n: window.i18n, - }), - }; - } - - if (isChatSessionRefreshed(attributes)) { - return { - emoji: '🔁', - text: window.i18n('icu:ChatRefresh--notification'), - }; - } - - if (isUnsupportedMessage(attributes)) { - return { - text: window.i18n('icu:message--getDescription--unsupported-message'), - }; - } - - if (isGroupV1Migration(attributes)) { - return { - text: window.i18n('icu:GroupV1--Migration--was-upgraded'), - }; - } - - if (isProfileChange(attributes)) { - const change = this.get('profileChange'); - const changedId = this.get('changedId'); - const changedContact = findAndFormatContact(changedId); - if (!change) { - throw new Error('getNotificationData: profileChange was missing!'); - } - - return { - text: getStringForProfileChange(change, changedContact, window.i18n), - }; - } - - if (isGroupV2Change(attributes)) { - const change = this.get('groupV2Change'); - strictAssert( - change, - 'getNotificationData: isGroupV2Change true, but no groupV2Change!' - ); - - const changes = GroupChange.renderChange(change, { - i18n: window.i18n, - ourACI: window.textsecure.storage.user - .getCheckedUuid(UUIDKind.ACI) - .toString(), - ourPNI: window.textsecure.storage.user - .getCheckedUuid(UUIDKind.PNI) - .toString(), - renderContact: (conversationId: string) => { - const conversation = - window.ConversationController.get(conversationId); - return conversation - ? conversation.getTitle() - : window.i18n('icu:unknownContact'); - }, - renderString: ( - key: string, - _i18n: unknown, - components: ReplacementValuesType | undefined - ) => { - // eslint-disable-next-line local-rules/valid-i18n-keys - return window.i18n(key, components); - }, - }); - - return { text: changes.map(({ text }) => text).join(' ') }; - } - - if (messageHasPaymentEvent(attributes)) { - const sender = findAndFormatContact(attributes.sourceUuid); - const conversation = findAndFormatContact(attributes.conversationId); - return { - text: getPaymentEventNotificationText( - attributes.payment, - sender.title, - conversation.title, - sender.isMe, - window.i18n - ), - emoji: '💳', - }; - } - - const attachments = this.get('attachments') || []; - - if (isTapToView(attributes)) { - if (this.isErased()) { - return { - text: window.i18n('icu:message--getDescription--disappearing-media'), - }; - } - - if (Attachment.isImage(attachments)) { - return { - text: window.i18n('icu:message--getDescription--disappearing-photo'), - emoji: 'đŸ“·', - }; - } - if (Attachment.isVideo(attachments)) { - return { - text: window.i18n('icu:message--getDescription--disappearing-video'), - emoji: 'đŸŽ„', - }; - } - // There should be an image or video attachment, but we have a fallback just in - // case. - return { text: window.i18n('icu:mediaMessage'), emoji: '📎' }; - } - - if (isGroupUpdate(attributes)) { - const groupUpdate = this.get('group_update'); - const fromContact = getContact(this.attributes); - const messages = []; - if (!groupUpdate) { - throw new Error('getNotificationData: Missing group_update'); - } - - if (groupUpdate.left === 'You') { - return { text: window.i18n('icu:youLeftTheGroup') }; - } - if (groupUpdate.left) { - return { - text: window.i18n('icu:leftTheGroup', { - name: this.getNameForNumber(groupUpdate.left), - }), - }; - } - - if (!fromContact) { - return { text: '' }; - } - - if (isMe(fromContact.attributes)) { - messages.push(window.i18n('icu:youUpdatedTheGroup')); - } else { - messages.push( - window.i18n('icu:updatedTheGroup', { - name: fromContact.getTitle(), - }) - ); - } - - if (groupUpdate.joined && groupUpdate.joined.length) { - const joinedContacts = groupUpdate.joined.map(item => - window.ConversationController.getOrCreate(item, 'private') - ); - const joinedWithoutMe = joinedContacts.filter( - contact => !isMe(contact.attributes) - ); - - if (joinedContacts.length > 1) { - messages.push( - window.i18n('icu:multipleJoinedTheGroup', { - names: joinedWithoutMe - .map(contact => contact.getTitle()) - .join(', '), - }) - ); - - if (joinedWithoutMe.length < joinedContacts.length) { - messages.push(window.i18n('icu:youJoinedTheGroup')); - } - } else { - const joinedContact = window.ConversationController.getOrCreate( - groupUpdate.joined[0], - 'private' - ); - if (isMe(joinedContact.attributes)) { - messages.push(window.i18n('icu:youJoinedTheGroup')); - } else { - messages.push( - window.i18n('icu:joinedTheGroup', { - name: joinedContacts[0].getTitle(), - }) - ); - } - } - } - - if (groupUpdate.name) { - messages.push( - window.i18n('icu:titleIsNow', { - name: groupUpdate.name, - }) - ); - } - if (groupUpdate.avatarUpdated) { - messages.push(window.i18n('icu:updatedGroupAvatar')); - } - - return { text: messages.join(' ') }; - } - if (isEndSession(attributes)) { - return { text: window.i18n('icu:sessionEnded') }; - } - if (isIncoming(attributes) && hasErrors(attributes)) { - return { text: window.i18n('icu:incomingError') }; - } - - const body = (this.get('body') || '').trim(); - const bodyRanges = this.get('bodyRanges') || []; - - if (attachments.length) { - // This should never happen but we want to be extra-careful. - const attachment = attachments[0] || {}; - const { contentType } = attachment; - - if (contentType === MIME.IMAGE_GIF || Attachment.isGIF(attachments)) { - return { - bodyRanges, - emoji: '🎡', - text: body || window.i18n('icu:message--getNotificationText--gif'), - }; - } - if (Attachment.isImage(attachments)) { - return { - bodyRanges, - emoji: 'đŸ“·', - text: body || window.i18n('icu:message--getNotificationText--photo'), - }; - } - if (Attachment.isVideo(attachments)) { - return { - bodyRanges, - emoji: 'đŸŽ„', - text: body || window.i18n('icu:message--getNotificationText--video'), - }; - } - if (Attachment.isVoiceMessage(attachment)) { - return { - bodyRanges, - emoji: 'đŸŽ€', - text: - body || - window.i18n('icu:message--getNotificationText--voice-message'), - }; - } - if (Attachment.isAudio(attachments)) { - return { - bodyRanges, - emoji: '🔈', - text: - body || - window.i18n('icu:message--getNotificationText--audio-message'), - }; - } - - return { - bodyRanges, - text: body || window.i18n('icu:message--getNotificationText--file'), - emoji: '📎', - }; - } - - const stickerData = this.get('sticker'); - if (stickerData) { - const emoji = - Stickers.getSticker(stickerData.packId, stickerData.stickerId)?.emoji || - stickerData?.emoji; - - if (!emoji) { - log.warn('Unable to get emoji for sticker'); - } - return { - text: window.i18n('icu:message--getNotificationText--stickers'), - emoji: dropNull(emoji), - }; - } - - if (isCallHistory(attributes)) { - const state = window.reduxStore.getState(); - const callingNotification = getPropsForCallHistory(attributes, { - conversationSelector: findAndFormatContact, - callSelector: getCallSelector(state), - activeCall: getActiveCall(state), - }); - if (callingNotification) { - return { - text: getCallingNotificationText(callingNotification, window.i18n), - }; - } - - log.error("This call history message doesn't have valid call history"); - } - if (isExpirationTimerUpdate(attributes)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const { expireTimer } = this.get('expirationTimerUpdate')!; - if (!expireTimer) { - return { text: window.i18n('icu:disappearingMessagesDisabled') }; - } - - return { - text: window.i18n('icu:timerSetTo', { - time: expirationTimer.format(window.i18n, expireTimer), - }), - }; - } - - if (isKeyChange(attributes)) { - const identifier = this.get('key_changed'); - const conversation = window.ConversationController.get(identifier); - return { - text: window.i18n('icu:safetyNumberChangedGroup', { - name: conversation ? conversation.getTitle() : '', - }), - }; - } - const contacts = this.get('contact'); - if (contacts && contacts.length) { - return { - text: - EmbeddedContact.getName(contacts[0]) || - window.i18n('icu:unknownContact'), - emoji: 'đŸ‘€', - }; - } - - const giftBadge = this.get('giftBadge'); - if (giftBadge) { - const emoji = '✹'; - - if (isOutgoing(this.attributes)) { - const toContact = window.ConversationController.get( - this.attributes.conversationId - ); - const recipient = - toContact?.getTitle() ?? window.i18n('icu:unknownContact'); - return { - emoji, - text: window.i18n('icu:message--donation--preview--sent', { - recipient, - }), - }; - } - - const fromContact = getContact(this.attributes); - const sender = - fromContact?.getTitle() ?? window.i18n('icu:unknownContact'); - return { - emoji, - text: - giftBadge.state === GiftBadgeStates.Unopened - ? window.i18n('icu:message--donation--preview--unopened', { - sender, - }) - : window.i18n('icu:message--donation--preview--redeemed'), - }; - } - - if (body) { - return { - text: body, - bodyRanges, - }; - } - - return { text: '' }; - } - - getAuthorText(): string | undefined { - // if it's outgoing, it must be self-authored - const selfAuthor = isOutgoing(this.attributes) - ? window.i18n('icu:you') - : undefined; - - // if it's not selfAuthor and there's no incoming contact, - // it might be a group notification, so we return undefined - return selfAuthor ?? this.getIncomingContact()?.getTitle({ isShort: true }); + return getNotificationDataForMessage(this.attributes); } getNotificationText(): string { - const { text, emoji } = this.getNotificationData(); - const { attributes } = this; - - const conversation = this.getConversation(); - - strictAssert( - conversation != null, - 'Conversation not found in ConversationController' - ); - - if (!isConversationAccepted(conversation.attributes)) { - return window.i18n('icu:message--getNotificationText--messageRequest'); - } - - if (attributes.storyReaction) { - if (attributes.type === 'outgoing') { - const name = this.getConversation()?.get('profileName'); - - if (!name) { - return window.i18n( - 'icu:Quote__story-reaction-notification--outgoing--nameless', - { - emoji: attributes.storyReaction.emoji, - } - ); - } - - return window.i18n('icu:Quote__story-reaction-notification--outgoing', { - emoji: attributes.storyReaction.emoji, - name, - }); - } - - const ourUuid = window.textsecure.storage.user - .getCheckedUuid() - .toString(); - - if ( - attributes.type === 'incoming' && - attributes.storyReaction.targetAuthorUuid === ourUuid - ) { - return window.i18n('icu:Quote__story-reaction-notification--incoming', { - emoji: attributes.storyReaction.emoji, - }); - } - - if (!window.Signal.OS.isLinux()) { - return attributes.storyReaction.emoji; - } - - return window.i18n('icu:Quote__story-reaction--single'); - } - - const mentions = - extractHydratedMentions(attributes, { - conversationSelector: findAndFormatContact, - }) || []; - const spoilers = (attributes.bodyRanges || []).filter( - range => - BodyRange.isFormatting(range) && range.style === BodyRange.Style.SPOILER - ) as Array>; - const modifiedText = applyRangesForText({ text, mentions, spoilers }); - - // Linux emoji support is mixed, so we disable it. (Note that this doesn't touch - // the `text`, which can contain emoji.) - const shouldIncludeEmoji = Boolean(emoji) && !window.Signal.OS.isLinux(); - if (shouldIncludeEmoji) { - return window.i18n('icu:message--getNotificationText--text-with-emoji', { - text: modifiedText, - emoji, - }); - } - - return modifiedText || ''; + return getNotificationTextForMessage(this.attributes); } // General @@ -915,14 +346,6 @@ export class MessageModel extends window.Backbone.Model { this.set(attributes); } - getNameForNumber(number: string): string { - const conversation = window.ConversationController.get(number); - if (!conversation) { - return number; - } - return conversation.getTitle(); - } - async cleanup(): Promise { await cleanupMessage(this.attributes); } @@ -993,11 +416,11 @@ export class MessageModel extends window.Backbone.Model { if (!fromSync) { const senderE164 = getSource(this.attributes); - const senderUuid = getSourceUuid(this.attributes); + const senderAci = getSourceServiceId(this.attributes); const timestamp = this.get('sent_at'); - if (senderUuid === undefined) { - throw new Error('markViewOnceMessageViewed: senderUuid is undefined'); + if (senderAci === undefined || !isAciString(senderAci)) { + throw new Error('markViewOnceMessageViewed: senderAci is undefined'); } if (window.ConversationController.areWePrimaryDevice()) { @@ -1012,7 +435,7 @@ export class MessageModel extends window.Backbone.Model { viewOnceOpens: [ { senderE164, - senderUuid, + senderAci, timestamp, }, ], @@ -1035,13 +458,13 @@ export class MessageModel extends window.Backbone.Model { `doubleCheckMissingQuoteReference/${logId}: missing story reference` ); - const message = window.MessageController.getById(storyId); + const message = window.MessageCache.__DEPRECATED$getById(storyId); if (!message) { return; } if (this.get('storyReplyContext')) { - this.unset('storyReplyContext'); + this.set('storyReplyContext', undefined); } await this.hydrateStoryContext(message.attributes, { shouldSave: true }); return; @@ -1053,8 +476,8 @@ export class MessageModel extends window.Backbone.Model { return; } - const { authorUuid, author, id: sentAt, referencedMessageNotFound } = quote; - const contact = window.ConversationController.get(authorUuid || author); + const { authorAci, author, id: sentAt, referencedMessageNotFound } = quote; + const contact = window.ConversationController.get(authorAci || author); // Is the quote really without a reference? Check with our in memory store // first to make sure it's not there. @@ -1062,7 +485,7 @@ export class MessageModel extends window.Backbone.Model { log.info( `doubleCheckMissingQuoteReference/${logId}: Verifying reference to ${sentAt}` ); - const inMemoryMessages = window.MessageController.filterBySentAt( + const inMemoryMessages = window.MessageCache.__DEPRECATED$filterBySentAt( Number(sentAt) ); let matchingMessage = find(inMemoryMessages, message => @@ -1076,7 +499,11 @@ export class MessageModel extends window.Backbone.Model { isQuoteAMatch(item, this.get('conversationId'), quote) ); if (found) { - matchingMessage = window.MessageController.register(found.id, found); + matchingMessage = window.MessageCache.__DEPRECATED$register( + found.id, + found, + 'doubleCheckMissingQuoteReference' + ); } } @@ -1143,17 +570,15 @@ export class MessageModel extends window.Backbone.Model { sticker: undefined, ...additionalProperties, }); - this.getConversation()?.debouncedUpdateLastMessage?.(); + this.getConversation()?.debouncedUpdateLastMessage(); if (shouldPersist) { await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } await window.Signal.Data.deleteSentProtoByMessageId(this.id); - - scheduleOptimizeFTS(); } override isEmpty(): boolean { @@ -1189,6 +614,7 @@ export class MessageModel extends window.Backbone.Model { const isUniversalTimerNotificationValue = isUniversalTimerNotification(attributes); const isConversationMergeValue = isConversationMerge(attributes); + const isPhoneNumberDiscoveryValue = isPhoneNumberDiscovery(attributes); const isPayment = messageHasPaymentEvent(attributes); @@ -1220,7 +646,8 @@ export class MessageModel extends window.Backbone.Model { isKeyChangeValue || isProfileChangeValue || isUniversalTimerNotificationValue || - isConversationMergeValue; + isConversationMergeValue || + isPhoneNumberDiscoveryValue; return !hasSomethingToDisplay; } @@ -1279,7 +706,7 @@ export class MessageModel extends window.Backbone.Model { if (!skipSave && !this.doNotSave) { await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } } @@ -1288,18 +715,6 @@ export class MessageModel extends window.Backbone.Model { this.set(markRead(this.attributes, readAt, options)); } - getIncomingContact(): ConversationModel | undefined | null { - if (!isIncoming(this.attributes)) { - return null; - } - const sourceUuid = this.get('sourceUuid'); - if (!sourceUuid) { - return null; - } - - return window.ConversationController.getOrCreate(sourceUuid, 'private'); - } - async retrySend(): Promise { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const conversation = this.getConversation()!; @@ -1321,7 +736,7 @@ export class MessageModel extends window.Backbone.Model { currentConversationRecipients = new Set( storyDistribution.members - .map(uuid => window.ConversationController.get(uuid)?.id) + .map(serviceId => window.ConversationController.get(serviceId)?.id) .filter(isNotNil) ); } else { @@ -1372,7 +787,7 @@ export class MessageModel extends window.Backbone.Model { async jobToInsert => { await window.Signal.Data.saveMessage(this.attributes, { jobToInsert, - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } ); @@ -1387,7 +802,7 @@ export class MessageModel extends window.Backbone.Model { async jobToInsert => { await window.Signal.Data.saveMessage(this.attributes, { jobToInsert, - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } ); @@ -1417,18 +832,40 @@ export class MessageModel extends window.Backbone.Model { * Change any Pending send state to Failed. Note that this will not mark successful * sends failed. */ - public markFailed(): void { + public markFailed(editMessageTimestamp?: number): void { const now = Date.now(); - this.set( - 'sendStateByConversationId', - mapValues(this.get('sendStateByConversationId') || {}, sendState => + + const targetTimestamp = editMessageTimestamp || this.get('timestamp'); + const sendStateByConversationId = getPropForTimestamp({ + log, + message: this, + prop: 'sendStateByConversationId', + targetTimestamp, + }); + + const newSendStateByConversationId = mapValues( + sendStateByConversationId || {}, + sendState => sendStateReducer(sendState, { type: SendActionType.Failed, updatedAt: now, }) - ) ); + setPropForTimestamp({ + log, + message: this, + prop: 'sendStateByConversationId', + targetTimestamp, + value: newSendStateByConversationId, + }); + + // We aren't trying to send this message anymore, so we'll delete these caches + delete this.cachedOutgoingContactData; + delete this.cachedOutgoingPreviewData; + delete this.cachedOutgoingQuoteData; + delete this.cachedOutgoingStickerData; + this.notifyStorySendFailed(); } @@ -1460,7 +897,7 @@ export class MessageModel extends window.Backbone.Model { e => window.ConversationController.getConversationId( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - e.identifier || e.number! + e.serviceId || e.number! ) === incomingConversationId && (e.name === 'MessageError' || e.name === 'OutgoingMessageError' || @@ -1472,12 +909,17 @@ export class MessageModel extends window.Backbone.Model { return errors[0][0]; } - async send( - promise: Promise, - saveErrors?: (errors: Array) => void - ): Promise { + async send({ + promise, + saveErrors, + targetTimestamp, + }: { + promise: Promise; + saveErrors?: (errors: Array) => void; + targetTimestamp: number; + }): Promise { const updateLeftPane = - this.getConversation()?.debouncedUpdateLastMessage || noop; + this.getConversation()?.debouncedUpdateLastMessage ?? noop; updateLeftPane(); @@ -1507,12 +949,17 @@ export class MessageModel extends window.Backbone.Model { if (!this.doNotSave) { await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } const sendStateByConversationId = { - ...(this.get('sendStateByConversationId') || {}), + ...(getPropForTimestamp({ + log, + message: this, + prop: 'sendStateByConversationId', + targetTimestamp, + }) || {}), }; const sendIsNotFinal = @@ -1520,17 +967,17 @@ export class MessageModel extends window.Backbone.Model { const sendIsFinal = !sendIsNotFinal; // Capture successful sends - const successfulIdentifiers: Array = + const successfulServiceIds: Array = sendIsFinal && - 'successfulIdentifiers' in result.value && - Array.isArray(result.value.successfulIdentifiers) - ? result.value.successfulIdentifiers + 'successfulServiceIds' in result.value && + Array.isArray(result.value.successfulServiceIds) + ? result.value.successfulServiceIds : []; const sentToAtLeastOneRecipient = - result.success || Boolean(successfulIdentifiers.length); + result.success || Boolean(successfulServiceIds.length); - successfulIdentifiers.forEach(identifier => { - const conversation = window.ConversationController.get(identifier); + successfulServiceIds.forEach(serviceId => { + const conversation = window.ConversationController.get(serviceId); if (!conversation) { return; } @@ -1556,9 +1003,13 @@ export class MessageModel extends window.Backbone.Model { }); // Integrate sends via sealed sender + const latestEditTimestamp = this.get('editMessageTimestamp'); + const sendIsLatest = + !latestEditTimestamp || targetTimestamp === latestEditTimestamp; const previousUnidentifiedDeliveries = this.get('unidentifiedDeliveries') || []; const newUnidentifiedDeliveries = + sendIsLatest && sendIsFinal && 'unidentifiedDeliveries' in result.value && Array.isArray(result.value.unidentifiedDeliveries) @@ -1586,7 +1037,7 @@ export class MessageModel extends window.Backbone.Model { errors.forEach(error => { const conversation = - window.ConversationController.get(error.identifier) || + window.ConversationController.get(error.serviceId) || window.ConversationController.get(error.number); if (conversation && !saveErrors && sendIsFinal) { @@ -1637,7 +1088,6 @@ export class MessageModel extends window.Backbone.Model { } }); - attributesToUpdate.sendStateByConversationId = sendStateByConversationId; // Only update the expirationStartTimestamp if we don't already have one set if (!this.get('expirationStartTimestamp')) { attributesToUpdate.expirationStartTimestamp = sentToAtLeastOneRecipient @@ -1659,22 +1109,31 @@ export class MessageModel extends window.Backbone.Model { void this.saveErrors(errorsToSave, { skipSave: true }); } + setPropForTimestamp({ + log, + message: this, + prop: 'sendStateByConversationId', + targetTimestamp, + value: sendStateByConversationId, + }); + if (!this.doNotSave) { await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } updateLeftPane(); if (sentToAtLeastOneRecipient && !this.doNotSendSyncMessage) { - promises.push(this.sendSyncMessage()); + promises.push(this.sendSyncMessage(targetTimestamp)); } await Promise.all(promises); const isTotalSuccess: boolean = result.success && !this.get('errors')?.length; + if (isTotalSuccess) { delete this.cachedOutgoingContactData; delete this.cachedOutgoingPreviewData; @@ -1685,10 +1144,15 @@ export class MessageModel extends window.Backbone.Model { updateLeftPane(); } - async sendSyncMessageOnly( - dataMessage: Uint8Array, - saveErrors?: (errors: Array) => void - ): Promise { + async sendSyncMessageOnly({ + targetTimestamp, + dataMessage, + saveErrors, + }: { + targetTimestamp: number; + dataMessage: Uint8Array; + saveErrors?: (errors: Array) => void; + }): Promise { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const conv = this.getConversation()!; this.set({ dataMessage }); @@ -1701,7 +1165,7 @@ export class MessageModel extends window.Backbone.Model { expirationStartTimestamp: Date.now(), errors: [], }); - const result = await this.sendSyncMessage(); + const result = await this.sendSyncMessage(targetTimestamp); this.set({ // We have to do this afterward, since we didn't have a previous send! unidentifiedDeliveries: @@ -1724,7 +1188,7 @@ export class MessageModel extends window.Backbone.Model { throw error; } finally { await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); if (updateLeftPane) { @@ -1733,7 +1197,9 @@ export class MessageModel extends window.Backbone.Model { } } - async sendSyncMessage(): Promise { + async sendSyncMessage( + targetTimestamp: number + ): Promise { const ourConversation = window.ConversationController.getOurConversationOrThrow(); const sendOptions = await getSendOptions(ourConversation.attributes, { @@ -1759,8 +1225,14 @@ export class MessageModel extends window.Backbone.Model { if (!dataMessage) { return; } - const isEditedMessage = Boolean(this.get('editHistory')); - const isUpdate = Boolean(this.get('synced')) && !isEditedMessage; + + const originalTimestamp = getMessageSentTimestamp(this.attributes, { + includeEdits: false, + log, + }); + const isSendingEdit = targetTimestamp !== originalTimestamp; + + const isUpdate = Boolean(this.get('synced')) && !isSendingEdit; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const conv = this.getConversation()!; @@ -1792,9 +1264,7 @@ export class MessageModel extends window.Backbone.Model { map(conversationsWithSealedSender, c => c.id) ); - const timestamp = getMessageSentTimestamp(this.attributes, { log }); - - const encodedContent = isEditedMessage + const encodedContent = isSendingEdit ? { encodedEditMessage: dataMessage, } @@ -1805,9 +1275,9 @@ export class MessageModel extends window.Backbone.Model { return handleMessageSend( messaging.sendSyncMessage({ ...encodedContent, - timestamp, + timestamp: targetTimestamp, destination: conv.get('e164'), - destinationUuid: getTaggedConversationUuid(conv.attributes), + destinationServiceId: conv.getServiceId(), expirationStartTimestamp: this.get('expirationStartTimestamp') || null, conversationIdsSentTo, @@ -1854,7 +1324,7 @@ export class MessageModel extends window.Backbone.Model { } await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); return result; }); @@ -1964,7 +1434,8 @@ export class MessageModel extends window.Backbone.Model { messageId: '', }; - const inMemoryMessages = window.MessageController.filterBySentAt(id); + const inMemoryMessages = + window.MessageCache.__DEPRECATED$filterBySentAt(id); const matchingMessage = find(inMemoryMessages, item => isQuoteAMatch(item.attributes, conversationId, result) ); @@ -1985,7 +1456,11 @@ export class MessageModel extends window.Backbone.Model { return result; } - queryMessage = window.MessageController.register(found.id, found); + queryMessage = window.MessageCache.__DEPRECATED$register( + found.id, + found, + 'copyFromQuotedMessage' + ); } if (queryMessage) { @@ -2001,6 +1476,7 @@ export class MessageModel extends window.Backbone.Model { ): Promise { const { attachments } = quote; const firstAttachment = attachments ? attachments[0] : undefined; + const firstThumbnailCdnFields = copyCdnFields(firstAttachment?.thumbnail); if (messageHasPaymentEvent(originalMessage.attributes)) { // eslint-disable-next-line no-param-reassign @@ -2076,7 +1552,7 @@ export class MessageModel extends window.Backbone.Model { ); originalMessage.set(upgradedMessage); await window.Signal.Data.saveMessage(upgradedMessage, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } } catch (error) { @@ -2094,6 +1570,7 @@ export class MessageModel extends window.Backbone.Model { if (thumbnail && thumbnail.path) { firstAttachment.thumbnail = { + ...firstThumbnailCdnFields, ...thumbnail, copied: true, }; @@ -2107,6 +1584,7 @@ export class MessageModel extends window.Backbone.Model { if (image && image.path) { firstAttachment.thumbnail = { + ...firstThumbnailCdnFields, ...image, copied: true, }; @@ -2116,6 +1594,7 @@ export class MessageModel extends window.Backbone.Model { const sticker = originalMessage.get('sticker'); if (sticker && sticker.data && sticker.data.path) { firstAttachment.thumbnail = { + ...firstThumbnailCdnFields, ...sticker.data, copied: true, }; @@ -2135,9 +1614,9 @@ export class MessageModel extends window.Backbone.Model { // 3. in rare cases, an incoming message can be retried, though it will // still go through one of the previous two codepaths // eslint-disable-next-line @typescript-eslint/no-this-alias - const message = this; + let message: MessageModel = this; const source = message.get('source'); - const sourceUuid = message.get('sourceUuid'); + const sourceServiceId = message.get('sourceServiceId'); const type = message.get('type'); const conversationId = message.get('conversationId'); @@ -2153,9 +1632,9 @@ export class MessageModel extends window.Backbone.Model { log.info(`${idLog}: starting processing in queue`); // First, check for duplicates. If we find one, stop processing here. - const inMemoryMessage = window.MessageController.findBySender( + const inMemoryMessage = window.MessageCache.findBySender( this.getSenderIdentifier() - )?.attributes; + ); if (inMemoryMessage) { log.info(`${idLog}: cache hit`, this.getSenderIdentifier()); } else { @@ -2186,9 +1665,10 @@ export class MessageModel extends window.Backbone.Model { `${idLog}: Updating message ${message.idForLogging()} with received transcript` ); - const toUpdate = window.MessageController.register( + const toUpdate = window.MessageCache.__DEPRECATED$register( existingMessage.id, - existingMessage + existingMessage, + 'handleDataMessage/outgoing/toUpdate' ); const unidentifiedDeliveriesSet = new Set( @@ -2204,17 +1684,15 @@ export class MessageModel extends window.Backbone.Model { : []; unidentifiedStatus.forEach( - ({ destinationUuid, destination, unidentified }) => { - const identifier = - destinationUuid?.aci || destinationUuid?.pni || destination; + ({ destinationServiceId, destination, unidentified }) => { + const identifier = destinationServiceId || destination; if (!identifier) { return; } - const { conversation: destinationConversation } = - window.ConversationController.maybeMergeContacts({ - aci: destinationUuid?.aci, - pni: destinationUuid?.pni, + const destinationConversation = + window.ConversationController.lookupOrCreate({ + serviceId: destinationServiceId, e164: destination || undefined, reason: `handleDataMessage(${initialMessage.timestamp})`, }); @@ -2253,7 +1731,7 @@ export class MessageModel extends window.Backbone.Model { unidentifiedDeliveries: [...unidentifiedDeliveriesSet], }); await window.Signal.Data.saveMessage(toUpdate.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); confirm(); @@ -2344,13 +1822,11 @@ export class MessageModel extends window.Backbone.Model { } } - const ourACI = window.textsecure.storage.user.getCheckedUuid( - UUIDKind.ACI - ); + const ourAci = window.textsecure.storage.user.getCheckedAci(); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const sender = window.ConversationController.lookupOrCreate({ e164: source, - uuid: sourceUuid, + serviceId: sourceServiceId, reason: 'handleDataMessage', })!; const hasGroupV2Prop = Boolean(initialMessage.groupV2); @@ -2358,7 +1834,8 @@ export class MessageModel extends window.Backbone.Model { // Drop if from blocked user. Only GroupV2 messages should need to be dropped here. const isBlocked = (source && window.storage.blocked.isBlocked(source)) || - (sourceUuid && window.storage.blocked.isUuidBlocked(sourceUuid)); + (sourceServiceId && + window.storage.blocked.isServiceIdBlocked(sourceServiceId)); if (isBlocked) { log.info( `${idLog}: Dropping message from blocked sender. hasGroupV2Prop: ${hasGroupV2Prop}` @@ -2369,7 +1846,7 @@ export class MessageModel extends window.Backbone.Model { } const areWeMember = - !conversation.get('left') && conversation.hasMember(ourACI); + !conversation.get('left') && conversation.hasMember(ourAci); // Drop an incoming GroupV2 message if we or the sender are not part of the group // after applying the message's associated group changes. @@ -2378,7 +1855,7 @@ export class MessageModel extends window.Backbone.Model { !isDirectConversation(conversation.attributes) && hasGroupV2Prop && (!areWeMember || - (sourceUuid && !conversation.hasMember(new UUID(sourceUuid)))) + (sourceServiceId && !conversation.hasMember(sourceServiceId))) ) { log.warn( `${idLog}: Received message destined for group, which we or the sender are not a part of. Dropping.` @@ -2407,15 +1884,15 @@ export class MessageModel extends window.Backbone.Model { } // Drop incoming messages to announcement only groups where sender is not admin - if ( - conversation.get('announcementsOnly') && - !conversation.isAdmin(UUID.checkedLookup(sender?.id)) - ) { - confirm(); - return; + if (conversation.get('announcementsOnly')) { + const senderServiceId = sender.getServiceId(); + if (!senderServiceId || !conversation.isAdmin(senderServiceId)) { + confirm(); + return; + } } - const messageId = message.get('id') || UUID.generate().toString(); + const messageId = message.get('id') || generateUuid(); // Send delivery receipts, but only for non-story sealed sender messages // and not for messages from unaccepted conversations @@ -2430,11 +1907,15 @@ export class MessageModel extends window.Backbone.Model { // The queue can be paused easily. drop( window.Whisper.deliveryReceiptQueue.add(() => { + strictAssert( + isAciString(sourceServiceId), + 'Incoming message must be from ACI' + ); window.Whisper.deliveryReceiptBatcher.add({ messageId, conversationId, senderE164: source, - senderUuid: sourceUuid, + senderAci: sourceServiceId, timestamp: this.get('sent_at'), isDirectConversation: isDirectConversation( conversation.attributes @@ -2449,7 +1930,7 @@ export class MessageModel extends window.Backbone.Model { if (storyContext) { storyContextLogId = `storyContext(${storyContext.sentTimestamp}, ` + - `${storyContext.authorUuid})`; + `${storyContext.authorAci})`; } const [quote, storyQuotes] = await Promise.all([ @@ -2463,8 +1944,8 @@ export class MessageModel extends window.Backbone.Model { const sendState = sendStateByConversationId[sender.id]; const storyQuoteIsFromSelf = - candidateQuote.get('sourceUuid') === - window.storage.user.getCheckedUuid().toString(); + candidateQuote.get('sourceServiceId') === + window.storage.user.getCheckedAci(); if (!storyQuoteIsFromSelf) { return true; @@ -2579,14 +2060,10 @@ export class MessageModel extends window.Backbone.Model { ); } - const ourPNI = window.textsecure.storage.user.getCheckedUuid( - UUIDKind.PNI - ); - const ourUuids: Set = new Set([ - ourACI.toString(), - ourPNI.toString(), - ]); + const ourPni = window.textsecure.storage.user.getCheckedPni(); + const ourServiceIds: Set = new Set([ourAci, ourPni]); + window.MessageCache.toMessageAttributes(this.attributes); message.set({ id: messageId, attachments: dataMessage.attachments, @@ -2606,9 +2083,9 @@ export class MessageModel extends window.Backbone.Model { if (!BodyRange.isMention(bodyRange)) { return false; } - return ourUuids.has( - normalizeUuid( - bodyRange.mentionUuid, + return ourServiceIds.has( + normalizeServiceId( + bodyRange.mentionAci, 'handleDataMessage: mentionsMe check' ) ); @@ -2687,7 +2164,7 @@ export class MessageModel extends window.Backbone.Model { message.set({ expirationTimerUpdate: { source, - sourceUuid, + sourceServiceId, expireTimer: initialMessage.expireTimer, }, }); @@ -2709,7 +2186,7 @@ export class MessageModel extends window.Backbone.Model { // point and these calls will return early. if (dataMessage.expireTimer) { void conversation.updateExpirationTimer(dataMessage.expireTimer, { - source: sourceUuid || source, + source: sourceServiceId || source, receivedAt: message.get('received_at'), receivedAtMS: message.get('received_at_ms'), sentAt: message.get('sent_at'), @@ -2722,7 +2199,7 @@ export class MessageModel extends window.Backbone.Model { !isEndSession(message.attributes) ) { void conversation.updateExpirationTimer(undefined, { - source: sourceUuid || source, + source: sourceServiceId || source, receivedAt: message.get('received_at'), receivedAtMS: message.get('received_at_ms'), sentAt: message.get('sent_at'), @@ -2735,8 +2212,7 @@ export class MessageModel extends window.Backbone.Model { const { profileKey } = initialMessage; if ( source === window.textsecure.storage.user.getNumber() || - sourceUuid === - window.textsecure.storage.user.getUuid()?.toString() + sourceServiceId === window.textsecure.storage.user.getAci() ) { conversation.set({ profileSharing: true }); } else if (isDirectConversation(conversation.attributes)) { @@ -2744,7 +2220,7 @@ export class MessageModel extends window.Backbone.Model { } else { const local = window.ConversationController.lookupOrCreate({ e164: source, - uuid: sourceUuid, + serviceId: sourceServiceId, reason: 'handleDataMessage:setProfileKey', }); void local?.setProfileKey(profileKey); @@ -2780,12 +2256,16 @@ export class MessageModel extends window.Backbone.Model { ) { conversation.set({ lastMessage: message.getNotificationText(), - lastMessageAuthor: message.getAuthorText(), + lastMessageAuthor: getMessageAuthorText(message.attributes), timestamp: message.get('sent_at'), }); } - window.MessageController.register(message.id, message); + message = window.MessageCache.__DEPRECATED$register( + message.id, + message, + 'handleDataMessage/message' + ); conversation.incrementMessageCount(); // If we sent a message in a given conversation, unarchive it! @@ -2813,7 +2293,7 @@ export class MessageModel extends window.Backbone.Model { if (!messaging) { throw new Error(`${idLog}: messaging is not available`); } - const response = await messaging.server.getBoostBadgesFromServer( + const response = await messaging.server.getSubscriptionConfiguration( userLanguages ); const boostBadgesByLevel = parseBoostBadgeListFromServer( @@ -2837,11 +2317,9 @@ export class MessageModel extends window.Backbone.Model { let queueStoryForDownload = false; if (isStory(message.attributes)) { - const isShowingStories = shouldShowStoriesView(reduxState); - - queueStoryForDownload = - isShowingStories || - (await shouldDownloadStory(conversation.attributes)); + queueStoryForDownload = await shouldDownloadStory( + conversation.attributes + ); } const shouldHoldOffDownload = @@ -2888,7 +2366,7 @@ export class MessageModel extends window.Backbone.Model { const isFirstRun = false; await this.modifyTargetMessage(conversation, isFirstRun); - if (await shouldReplyNotifyUser(this, conversation)) { + if (await shouldReplyNotifyUser(this.attributes, conversation)) { await conversation.notify(this); } @@ -2921,7 +2399,7 @@ export class MessageModel extends window.Backbone.Model { } async handleReaction( - reaction: ReactionModel, + reaction: ReactionAttributesType, { storyMessage, shouldPersist = true, @@ -2954,22 +2432,20 @@ export class MessageModel extends window.Backbone.Model { return; } - const isFromThisDevice = - reaction.get('source') === ReactionSource.FromThisDevice; - const isFromSync = reaction.get('source') === ReactionSource.FromSync; + const isFromThisDevice = reaction.source === ReactionSource.FromThisDevice; + const isFromSync = reaction.source === ReactionSource.FromSync; const isFromSomeoneElse = - reaction.get('source') === ReactionSource.FromSomeoneElse; + reaction.source === ReactionSource.FromSomeoneElse; strictAssert( isFromThisDevice || isFromSync || isFromSomeoneElse, 'Reaction can only be from this device, from sync, or from someone else' ); const newReaction: MessageReactionType = { - emoji: reaction.get('remove') ? undefined : reaction.get('emoji'), - fromId: reaction.get('fromId'), - targetAuthorUuid: reaction.get('targetAuthorUuid'), - targetTimestamp: reaction.get('targetTimestamp'), - timestamp: reaction.get('timestamp'), + emoji: reaction.remove ? undefined : reaction.emoji, + fromId: reaction.fromId, + targetTimestamp: reaction.targetTimestamp, + timestamp: reaction.timestamp, isSentByConversationId: isFromThisDevice ? zipObject(conversation.getMemberConversationIds(), repeat(false)) : undefined, @@ -2996,7 +2472,7 @@ export class MessageModel extends window.Backbone.Model { ); } - const generatedMessage = reaction.get('storyReactionMessage'); + const generatedMessage = reaction.storyReactionMessage; strictAssert( generatedMessage, 'Story reactions must provide storyReactionMessage' @@ -3015,9 +2491,9 @@ export class MessageModel extends window.Backbone.Model { : undefined, storyId: storyMessage.id, storyReaction: { - emoji: reaction.get('emoji'), - targetAuthorUuid: reaction.get('targetAuthorUuid'), - targetTimestamp: reaction.get('targetTimestamp'), + emoji: reaction.emoji, + targetAuthorAci: reaction.targetAuthorAci, + targetTimestamp: reaction.targetTimestamp, }, }); @@ -3026,7 +2502,7 @@ export class MessageModel extends window.Backbone.Model { }); // Note: generatedMessage comes with an id, so we have to force this save await window.Signal.Data.saveMessage(generatedMessage.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), forceSave: true, }); @@ -3035,13 +2511,14 @@ export class MessageModel extends window.Backbone.Model { generatedMessage.attributes ), storyId: getMessageIdForLogging(storyMessage), - targetTimestamp: reaction.get('targetTimestamp'), - timestamp: reaction.get('timestamp'), + targetTimestamp: reaction.targetTimestamp, + timestamp: reaction.timestamp, }); - const messageToAdd = window.MessageController.register( + const messageToAdd = window.MessageCache.__DEPRECATED$register( generatedMessage.id, - generatedMessage + generatedMessage, + 'generatedMessage' ); if (isDirectConversation(targetConversation.attributes)) { await targetConversation.addSingleMessage(messageToAdd); @@ -3060,7 +2537,12 @@ export class MessageModel extends window.Backbone.Model { 'handleReaction: notifying for story reaction to ' + `${getMessageIdForLogging(storyMessage)} from someone else` ); - if (await shouldReplyNotifyUser(messageToAdd, targetConversation)) { + if ( + await shouldReplyNotifyUser( + messageToAdd.attributes, + targetConversation + ) + ) { drop(targetConversation.notify(messageToAdd)); } } @@ -3090,7 +2572,7 @@ export class MessageModel extends window.Backbone.Model { this.clearNotifications(oldReaction); } - if (reaction.get('remove')) { + if (reaction.remove) { log.info( 'handleReaction: removing reaction for message', this.idForLogging() @@ -3100,7 +2582,7 @@ export class MessageModel extends window.Backbone.Model { reactions = oldReactions.filter( re => !isNewReactionReplacingPrevious(re, newReaction) || - re.timestamp > reaction.get('timestamp') + re.timestamp > reaction.timestamp ); } else { reactions = oldReactions.filter( @@ -3110,10 +2592,10 @@ export class MessageModel extends window.Backbone.Model { this.set({ reactions }); await window.Signal.Data.removeReactionFromConversation({ - emoji: reaction.get('emoji'), - fromId: reaction.get('fromId'), - targetAuthorUuid: reaction.get('targetAuthorUuid'), - targetTimestamp: reaction.get('targetTimestamp'), + emoji: reaction.emoji, + fromId: reaction.fromId, + targetAuthorServiceId: reaction.targetAuthorAci, + targetTimestamp: reaction.targetTimestamp, }); } else { log.info( @@ -3125,9 +2607,7 @@ export class MessageModel extends window.Backbone.Model { if (isFromSync) { const ourReactions = [ newReaction, - ...oldReactions.filter( - re => re.fromId === reaction.get('fromId') - ), + ...oldReactions.filter(re => re.fromId === reaction.fromId), ]; reactionToAdd = maxBy(ourReactions, 'timestamp') || newReaction; } else { @@ -3135,7 +2615,7 @@ export class MessageModel extends window.Backbone.Model { } reactions = oldReactions.filter( - re => !isNewReactionReplacingPrevious(re, reaction.attributes) + re => !isNewReactionReplacingPrevious(re, reaction) ); reactions.push(reactionToAdd); this.set({ reactions }); @@ -3146,12 +2626,12 @@ export class MessageModel extends window.Backbone.Model { await window.Signal.Data.addReaction({ conversationId: this.get('conversationId'), - emoji: reaction.get('emoji'), - fromId: reaction.get('fromId'), + emoji: reaction.emoji, + fromId: reaction.fromId, messageId: this.id, messageReceivedAt: this.get('received_at'), - targetAuthorUuid: reaction.get('targetAuthorUuid'), - targetTimestamp: reaction.get('targetTimestamp'), + targetAuthorAci: reaction.targetAuthorAci, + targetTimestamp: reaction.targetTimestamp, }); } } @@ -3172,7 +2652,7 @@ export class MessageModel extends window.Backbone.Model { 'New story reaction must have an emoji' ); - const generatedMessage = reaction.get('storyReactionMessage'); + const generatedMessage = reaction.storyReactionMessage; strictAssert( generatedMessage, 'Story reactions must provide storyReactionmessage' @@ -3182,14 +2662,15 @@ export class MessageModel extends window.Backbone.Model { shouldSave: false, }); await window.Signal.Data.saveMessage(generatedMessage.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), forceSave: true, }); void conversation.addSingleMessage( - window.MessageController.register( + window.MessageCache.__DEPRECATED$register( generatedMessage.id, - generatedMessage + generatedMessage, + 'generatedMessage2' ) ); @@ -3216,7 +2697,7 @@ export class MessageModel extends window.Backbone.Model { ); await window.Signal.Data.saveMessage(this.attributes, { jobToInsert, - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); }); } else { @@ -3224,7 +2705,7 @@ export class MessageModel extends window.Backbone.Model { } } else if (shouldPersist && !isStory(this.attributes)) { await window.Signal.Data.saveMessage(this.attributes, { - ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), + ourAci: window.textsecure.storage.user.getCheckedAci(), }); } } @@ -3284,14 +2765,3 @@ export class MessageModel extends window.Backbone.Model { } window.Whisper.Message = MessageModel; - -window.Whisper.MessageCollection = window.Backbone.Collection.extend({ - model: window.Whisper.Message, - comparator(left: Readonly, right: Readonly) { - if (left.get('received_at') === right.get('received_at')) { - return (left.get('sent_at') || 0) - (right.get('sent_at') || 0); - } - - return (left.get('received_at') || 0) - (right.get('received_at') || 0); - }, -}); diff --git a/ts/quill/memberRepository.ts b/ts/quill/memberRepository.ts index 761e9875e1..e7d0ab4f0e 100644 --- a/ts/quill/memberRepository.ts +++ b/ts/quill/memberRepository.ts @@ -5,8 +5,37 @@ import Fuse from 'fuse.js'; import { get } from 'lodash'; import type { ConversationType } from '../state/ducks/conversations'; +import type { AciString } from '../types/ServiceId'; +import { isAciString } from '../util/isAciString'; import { filter, map } from '../util/iterables'; import { removeDiacritics } from '../util/removeDiacritics'; +import { isNotNil } from '../util/isNotNil'; + +export type MemberType = Omit & + Readonly<{ + aci: AciString; + }>; + +function toMember({ + serviceId, + ...restOfConvo +}: ConversationType): MemberType | undefined { + if (!isAciString(serviceId)) { + return undefined; + } + + return { + ...restOfConvo, + aci: serviceId, + }; +} + +// Exported for testing +export function _toMembers( + conversations: ReadonlyArray +): Array { + return conversations.map(toMember).filter(isNotNil); +} const FUSE_OPTIONS = { location: 0, @@ -16,7 +45,7 @@ const FUSE_OPTIONS = { minMatchCharLength: 1, keys: ['name', 'firstName', 'profileName', 'title'], getFn( - conversation: Readonly, + conversation: Readonly, path: string | Array ): ReadonlyArray | string { // It'd be nice to avoid this cast, but Fuse's types don't allow it. @@ -39,21 +68,21 @@ const FUSE_OPTIONS = { }; export class MemberRepository { + private members: ReadonlyArray; private isFuseReady = false; - private fuse: Fuse = new Fuse( - [], - FUSE_OPTIONS - ); + private fuse = new Fuse([], FUSE_OPTIONS); - constructor(private members: ReadonlyArray = []) {} + constructor(conversations: ReadonlyArray = []) { + this.members = _toMembers(conversations); + } - updateMembers(members: ReadonlyArray): void { - this.members = members; + updateMembers(conversations: ReadonlyArray): void { + this.members = _toMembers(conversations); this.isFuseReady = false; } - getMembers(omit?: ConversationType): ReadonlyArray { + getMembers(omit?: Pick): ReadonlyArray { if (omit) { return this.members.filter(({ id }) => id !== omit.id); } @@ -61,22 +90,22 @@ export class MemberRepository { return this.members; } - getMemberById(id?: string): ConversationType | undefined { + getMemberById(id?: string): MemberType | undefined { return id ? this.members.find(({ id: memberId }) => memberId === id) : undefined; } - getMemberByUuid(uuid?: string): ConversationType | undefined { - return uuid - ? this.members.find(({ uuid: memberUuid }) => memberUuid === uuid) + getMemberByAci(aci?: AciString): MemberType | undefined { + return aci + ? this.members.find(({ aci: memberAci }) => memberAci === aci) : undefined; } search( pattern: string, - omit?: ConversationType - ): ReadonlyArray { + omit?: Pick + ): ReadonlyArray { if (!this.isFuseReady) { this.fuse.setCollection(this.members); this.isFuseReady = true; diff --git a/ts/quill/mentions/blot.tsx b/ts/quill/mentions/blot.tsx index bdffa169e1..4d39f30acb 100644 --- a/ts/quill/mentions/blot.tsx +++ b/ts/quill/mentions/blot.tsx @@ -8,6 +8,7 @@ import Parchment from 'parchment'; import Quill from 'quill'; import { render } from 'react-dom'; import { Emojify } from '../../components/conversation/Emojify'; +import { normalizeAci } from '../../util/normalizeAci'; import type { MentionBlotValue } from '../util'; declare class QuillEmbed extends Parchment.Embed { @@ -32,21 +33,21 @@ export class MentionBlot extends Embed { } static override value(node: HTMLElement): MentionBlotValue { - const { uuid, title } = node.dataset; - if (uuid === undefined || title === undefined) { + const { aci, title } = node.dataset; + if (aci === undefined || title === undefined) { throw new Error( - `Failed to make MentionBlot with uuid: ${uuid}, title: ${title}` + `Failed to make MentionBlot with aci: ${aci}, title: ${title}` ); } return { - uuid, + aci: normalizeAci(aci, 'quill mention blot'), title, }; } static buildSpan(mention: MentionBlotValue, node: HTMLElement): void { - node.setAttribute('data-uuid', mention.uuid || ''); + node.setAttribute('data-aci', mention.aci || ''); node.setAttribute('data-title', mention.title || ''); node.setAttribute('contenteditable', 'false'); diff --git a/ts/quill/mentions/completion.tsx b/ts/quill/mentions/completion.tsx index a0c5e32c5c..10ce086fe9 100644 --- a/ts/quill/mentions/completion.tsx +++ b/ts/quill/mentions/completion.tsx @@ -13,9 +13,10 @@ import { createPortal } from 'react-dom'; import type { ConversationType } from '../../state/ducks/conversations'; import { Avatar, AvatarSize } from '../../components/Avatar'; import type { LocalizerType, ThemeType } from '../../types/Util'; -import type { MemberRepository } from '../memberRepository'; +import type { MemberType, MemberRepository } from '../memberRepository'; import type { PreferredBadgeSelectorType } from '../../state/selectors/badges'; import { matchBlotTextPartitions } from '../util'; +import type { MentionBlotValue } from '../util'; import { handleOutsideClick } from '../../util/handleOutsideClick'; import { sameWidthModifier } from '../../util/popperUtil'; import { UserText } from '../../components/UserText'; @@ -29,10 +30,10 @@ export type MentionCompletionOptions = { theme: ThemeType; }; -const MENTION_REGEX = /(?:^|\W)@([-+\p{L}\p{M}\p{N}]+)$/u; +const MENTION_REGEX = /(?:^|\W)@([-+\p{L}\p{M}\p{N}]*)$/u; export class MentionCompletion { - results: ReadonlyArray; + results: ReadonlyArray; index: number; @@ -106,7 +107,7 @@ export class MentionCompletion { this.clearResults(); } - possiblyShowMemberResults(): ReadonlyArray { + possiblyShowMemberResults(): ReadonlyArray { const range = this.quill.getSelection(); if (range) { @@ -121,7 +122,7 @@ export class MentionCompletion { if (leftTokenTextMatch) { const [, leftTokenText] = leftTokenTextMatch; - let results: ReadonlyArray = []; + let results: ReadonlyArray = []; const memberRepository = this.options.memberRepositoryRef.current; @@ -194,7 +195,7 @@ export class MentionCompletion { } insertMention( - mention: ConversationType, + member: MemberType, index: number, range: number, withTrailingSpace = false @@ -202,6 +203,11 @@ export class MentionCompletion { // The mention + space we add won't be formatted unless we manually provide attributes const attributes = this.getAttributesForInsert(range - 1); + const mention: MentionBlotValue = { + aci: member.aci, + title: member.title, + }; + const delta = new Delta() .retain(index) .delete(range) @@ -261,7 +267,7 @@ export class MentionCompletion { {memberResults.map((member, index) => (