From 500c0c0c822fb2a1854b132c0c7c384d46841ccb Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Fri, 6 Jun 2025 13:55:40 +1000 Subject: [PATCH 1/2] chore: run from artefact url --- .github/workflows/desktop-regression.yml | 148 ++++++++--------------- tests/automation/setup/open.ts | 22 ++-- 2 files changed, 61 insertions(+), 109 deletions(-) diff --git a/.github/workflows/desktop-regression.yml b/.github/workflows/desktop-regression.yml index 9e2a6f1..5d33003 100644 --- a/.github/workflows/desktop-regression.yml +++ b/.github/workflows/desktop-regression.yml @@ -2,37 +2,11 @@ name: Run desktop regression tests on: workflow_dispatch: inputs: - PLAYWRIGHT_REPO: - description: 'Playwright repo to checkout' - required: true - type: choice - options: - - session-foundation/session-playwright - - burtonemily/session-playwright - - bilb/session-playwright - default: session-foundation/session-playwright - - BRANCH_TO_CHECKOUT_PW: - description: 'branch to checkout on session-playwright' + DESKTOP_JOB_URL: + description: 'URL of the job on session-foundation/session-desktop' required: true type: string - default: regression-tests-groups - - SESSION_DESKTOP_REPO: - description: 'Session desktop repo to checkout' - required: true - type: choice - options: - - session-foundation/session-desktop - - bilb/session-desktop - - yougotwill/session-desktop - default: session-foundation/session-desktop - - BRANCH_TO_CHECKOUT_SESSION: - description: 'Branch to checkout on session-desktop' - required: true - type: string - default: dev + default: https://github.com/session-foundation/session-desktop/actions/runs/15481004324 PLAYWRIGHT_REPEAT_COUNT: description: 'Repeats of each tests (0 to only run each once)' @@ -50,7 +24,7 @@ on: description: 'Playwright workers to start' required: true type: number - default: 8 + default: 1 concurrency: group: ${{ github.workflow }} @@ -65,105 +39,83 @@ jobs: options: --cpus 16 env: + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} PLAYWRIGHT_REPEAT_COUNT: ${{ github.event.inputs.PLAYWRIGHT_REPEAT_COUNT }} PLAYWRIGHT_RETRIES_COUNT: ${{ github.event.inputs.PLAYWRIGHT_RETRIES_COUNT }} PLAYWRIGHT_WORKERS_COUNT: ${{ github.event.inputs.PLAYWRIGHT_WORKERS_COUNT }} - DESKTOP_CACHED_FOLDER: desktop/node_modules + DESKTOP_JOB_URL: ${{ github.event.inputs.DESKTOP_JOB_URL }} + ARTIFACT_NAME: 'Linux-X64-AppImage-qa-production' + CI: true steps: - - uses: actions/checkout@v4 - name: Runner Details run: | - echo "PLAYWRIGHT_REPO ${{ github.event.inputs.PLAYWRIGHT_REPO }}" - echo "BRANCH_TO_CHECKOUT_PW ${{ github.event.inputs.BRANCH_TO_CHECKOUT_PW }}" - echo "SESSION_DESKTOP_REPO ${{ github.event.inputs.SESSION_DESKTOP_REPO }}" - echo "BRANCH_TO_CHECKOUT_SESSION ${{ github.event.inputs.BRANCH_TO_CHECKOUT_SESSION }}" - - - uses: actions/checkout@v4 - name: 'Checkout playwright' - with: - repository: ${{ github.event.inputs.PLAYWRIGHT_REPO }} - ref: ${{ github.event.inputs.BRANCH_TO_CHECKOUT_PW }} - path: 'playwright' + echo "DESKTOP_JOB_URL ${{ github.event.inputs.DESKTOP_JOB_URL }}" + echo "PLAYWRIGHT_REPEAT_COUNT ${{ github.event.inputs.PLAYWRIGHT_REPEAT_COUNT }}" + echo "PLAYWRIGHT_RETRIES_COUNT ${{ github.event.inputs.PLAYWRIGHT_RETRIES_COUNT }}" + echo "PLAYWRIGHT_WORKERS_COUNT ${{ github.event.inputs.PLAYWRIGHT_WORKERS_COUNT }}" - - name: Install system deps - run: apt update && apt install -y git g++ build-essential cmake + - name: Install git lfs + run: | + apt-get update && \ + apt-get install -y git-lfs unzip jq libfuse2 && \ + git lfs install \ + modprobe fuse - uses: actions/checkout@v4 - name: 'Checkout Session desktop' with: - repository: ${{ github.event.inputs.SESSION_DESKTOP_REPO }} - ref: ${{ github.event.inputs.BRANCH_TO_CHECKOUT_SESSION }} - path: 'desktop' + lfs: true - # Note: caching is breaking things up (app doesn't start) - # - name: Calculate desktop cache key - # run: | - # echo "CACHE_KEY=${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('desktop/package.json', 'desktop/yarn.lock', 'desktop/patches/**') }}" >> $GITHUB_ENV + - name: 'Download prebuilt session-desktop' + run: | + RUN_ID=$(echo "$DESKTOP_JOB_URL" | sed -E 's|.*/runs/([0-9]+).*|\1|') + echo "Run ID: $RUN_ID" - - name: Install node - uses: actions/setup-node@v3 - with: - node-version-file: 'desktop/.nvmrc' + response=$(curl -s -H "Authorization: Bearer $PAT_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/session-foundation/session-desktop/actions/runs/$RUN_ID/artifacts") + echo "response: $response" - - uses: actions/setup-python@v4 - with: - python-version: '3.12' + artifact_url=$(echo "$response" | jq -r \ + --arg name "$ARTIFACT_NAME" \ + '.artifacts[] | select(.name == $name) | .archive_download_url') - - name: Install setuptools for python 3.12 - shell: bash - run: python -m pip install --upgrade pip setuptools - # Note: caching is breaking things up (app doesn't start) - # - uses: actions/cache/restore@v4 - # id: cache-desktop-modules - # with: - # path: ${{ env.DESKTOP_CACHED_FOLDER }} - # key: ${{ env.CACHE_KEY }} + echo "Session desktop Artifact URL: $artifact_url" - - name: Install yarn - run: | - npm install -g yarn + curl -L \ + -H "Authorization: token $PAT_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -o artifact.zip \ + $artifact_url - - name: List desktop folder - run: | - pwd - ls -la desktop + unzip artifact.zip - - name: List playwright folder + - name: 'print files' run: | - pwd - ls -la playwright - - - name: Install desktop dependencies - shell: bash - # if: steps.cache-desktop-modules.outputs.cache-hit != 'true' - run: cd $GITHUB_WORKSPACE/desktop && yarn install --frozen-lockfile --network-timeout 600000 + ls -l - # Note: caching is breaking things up (app doesn't start) - # - uses: actions/cache/save@v4 - # if: always() - # with: - # path: ${{ env.DESKTOP_CACHED_FOLDER }} - # key: ${{ env.CACHE_KEY }} + - name: Install node + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' - - name: Build desktop - shell: bash - run: cd $GITHUB_WORKSPACE/desktop && yarn build-everything + - name: Install yarn + run: | + npm install -g yarn - - name: Install playwright dependencies + - name: Install dependencies run: | - cd $GITHUB_WORKSPACE/playwright && yarn install --frozen-lockfile + yarn install --frozen-lockfile - name: Build the Desktop tests run: | - cd $GITHUB_WORKSPACE/playwright + cd $GITHUB_WORKSPACE yarn tsc - name: Run the Desktop tests run: | - cd $GITHUB_WORKSPACE/playwright - SESSION_DESKTOP_ROOT=$GITHUB_WORKSPACE/desktop nice ionice xvfb-run --auto-servernum --server-num=1 --server-args='-screen 0, 1920x1080x24' yarn test + DEBUG="pw:*" PRINT_ONGOING_TESTS=1 SESSION_DESKTOP_ROOT=$GITHUB_WORKSPACE/desktop nice ionice xvfb-run --auto-servernum --server-num=1 --server-args='-screen 0, 1920x1080x24' yarn test # DEBUG="pw:*" - name: Kill all running electron app diff --git a/tests/automation/setup/open.ts b/tests/automation/setup/open.ts index 7431a2f..3cb87e5 100644 --- a/tests/automation/setup/open.ts +++ b/tests/automation/setup/open.ts @@ -26,20 +26,20 @@ const openElectronAppOnly = async (multi: string) => { process.env.NODE_ENV = NODE_ENV; process.env.SESSION_DEBUG = '1'; - // if (!isEmpty(process.env.CI)) { - // const sessionBinPath = getSessionDesktopBinPath(); - // const fakeHome = `/tmp/${process.env.NODE_APP_INSTANCE}`; + if (!isEmpty(process.env.CI)) { + const sessionBinPath = './session-desktop-linux-x86_64-1.16.2.AppImage'; + const fakeHome = `/tmp/${process.env.NODE_APP_INSTANCE}`; - // console.info(` CI RUN`); - // console.info(` SESSION_BIN_PATH=${sessionBinPath}`); - // console.info(` HOME="${fakeHome}"`); + console.info(` CI RUN`); + console.info(` SESSION_BIN_PATH=${sessionBinPath}`); + console.info(` HOME="${fakeHome}"`); - // process.env.HOME = fakeHome; + process.env.HOME = fakeHome; - // return electron.launch({ - // executablePath: sessionBinPath, - // }); - // } + return electron.launch({ + executablePath: sessionBinPath, + }); + } console.info(` NON CI RUN`); console.info(' NODE_ENV', process.env.NODE_ENV); console.info(' NODE_APP_INSTANCE', process.env.NODE_APP_INSTANCE); From 1d91c590a1f561d67c43d35595e8d6a753db260f Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 2 Jul 2025 11:45:09 +1000 Subject: [PATCH 2/2] WIP --- .github/workflows/desktop-regression.yml | 148 +- .../avatar-updated-blue-darwin.jpeg | 3 - .../avatar-updated-blue-darwin.jpeg | 3 - .../new-account-darwin.png | 3 - .../restored-account-darwin.png | 3 - tests/automation/create_user.spec.ts | 4 +- .../disappearing_message_checks.spec.ts | 2 +- .../automation/disappearing_messages.spec.ts | 2 +- .../automation/enforce_localized_str.spec.ts | 10 +- tests/automation/group_testing.spec.ts | 10 +- tests/automation/input_validations.spec.ts | 8 +- tests/automation/landing_page.spec.ts | 6 + tests/automation/linked_device_group.spec.ts | 14 +- tests/automation/linked_device_user.spec.ts | 10 +- tests/automation/message_checks.spec.ts | 2 +- tests/automation/setup/new_user.ts | 6 +- tests/automation/setup/open.ts | 22 +- tests/automation/types/testing.ts | 19 +- tests/automation/user_actions.spec.ts | 10 +- tests/automation/utilities/rename_group.ts | 8 +- .../utilities/set_disappearing_messages.ts | 7 +- tests/localization/Localizer.ts | 13 +- tests/localization/constants.ts | 11 +- tests/localization/locales.ts | 3788 +++++++++-------- 24 files changed, 2215 insertions(+), 1897 deletions(-) delete mode 100644 screenshots/Change-avatar/avatar-updated-blue-darwin.jpeg delete mode 100644 screenshots/Profile-picture-syncs/avatar-updated-blue-darwin.jpeg delete mode 100644 screenshots/landing-page-states/new-account-darwin.png delete mode 100644 screenshots/landing-page-states/restored-account-darwin.png diff --git a/.github/workflows/desktop-regression.yml b/.github/workflows/desktop-regression.yml index 5d33003..9e2a6f1 100644 --- a/.github/workflows/desktop-regression.yml +++ b/.github/workflows/desktop-regression.yml @@ -2,11 +2,37 @@ name: Run desktop regression tests on: workflow_dispatch: inputs: - DESKTOP_JOB_URL: - description: 'URL of the job on session-foundation/session-desktop' + PLAYWRIGHT_REPO: + description: 'Playwright repo to checkout' + required: true + type: choice + options: + - session-foundation/session-playwright + - burtonemily/session-playwright + - bilb/session-playwright + default: session-foundation/session-playwright + + BRANCH_TO_CHECKOUT_PW: + description: 'branch to checkout on session-playwright' required: true type: string - default: https://github.com/session-foundation/session-desktop/actions/runs/15481004324 + default: regression-tests-groups + + SESSION_DESKTOP_REPO: + description: 'Session desktop repo to checkout' + required: true + type: choice + options: + - session-foundation/session-desktop + - bilb/session-desktop + - yougotwill/session-desktop + default: session-foundation/session-desktop + + BRANCH_TO_CHECKOUT_SESSION: + description: 'Branch to checkout on session-desktop' + required: true + type: string + default: dev PLAYWRIGHT_REPEAT_COUNT: description: 'Repeats of each tests (0 to only run each once)' @@ -24,7 +50,7 @@ on: description: 'Playwright workers to start' required: true type: number - default: 1 + default: 8 concurrency: group: ${{ github.workflow }} @@ -39,83 +65,105 @@ jobs: options: --cpus 16 env: - PAT_TOKEN: ${{ secrets.PAT_TOKEN }} PLAYWRIGHT_REPEAT_COUNT: ${{ github.event.inputs.PLAYWRIGHT_REPEAT_COUNT }} PLAYWRIGHT_RETRIES_COUNT: ${{ github.event.inputs.PLAYWRIGHT_RETRIES_COUNT }} PLAYWRIGHT_WORKERS_COUNT: ${{ github.event.inputs.PLAYWRIGHT_WORKERS_COUNT }} - DESKTOP_JOB_URL: ${{ github.event.inputs.DESKTOP_JOB_URL }} - ARTIFACT_NAME: 'Linux-X64-AppImage-qa-production' - CI: true + DESKTOP_CACHED_FOLDER: desktop/node_modules steps: + - uses: actions/checkout@v4 - name: Runner Details run: | - echo "DESKTOP_JOB_URL ${{ github.event.inputs.DESKTOP_JOB_URL }}" - echo "PLAYWRIGHT_REPEAT_COUNT ${{ github.event.inputs.PLAYWRIGHT_REPEAT_COUNT }}" - echo "PLAYWRIGHT_RETRIES_COUNT ${{ github.event.inputs.PLAYWRIGHT_RETRIES_COUNT }}" - echo "PLAYWRIGHT_WORKERS_COUNT ${{ github.event.inputs.PLAYWRIGHT_WORKERS_COUNT }}" - - - name: Install git lfs - run: | - apt-get update && \ - apt-get install -y git-lfs unzip jq libfuse2 && \ - git lfs install \ - modprobe fuse + echo "PLAYWRIGHT_REPO ${{ github.event.inputs.PLAYWRIGHT_REPO }}" + echo "BRANCH_TO_CHECKOUT_PW ${{ github.event.inputs.BRANCH_TO_CHECKOUT_PW }}" + echo "SESSION_DESKTOP_REPO ${{ github.event.inputs.SESSION_DESKTOP_REPO }}" + echo "BRANCH_TO_CHECKOUT_SESSION ${{ github.event.inputs.BRANCH_TO_CHECKOUT_SESSION }}" - uses: actions/checkout@v4 + name: 'Checkout playwright' with: - lfs: true + repository: ${{ github.event.inputs.PLAYWRIGHT_REPO }} + ref: ${{ github.event.inputs.BRANCH_TO_CHECKOUT_PW }} + path: 'playwright' - - name: 'Download prebuilt session-desktop' - run: | - RUN_ID=$(echo "$DESKTOP_JOB_URL" | sed -E 's|.*/runs/([0-9]+).*|\1|') - echo "Run ID: $RUN_ID" + - name: Install system deps + run: apt update && apt install -y git g++ build-essential cmake - response=$(curl -s -H "Authorization: Bearer $PAT_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/session-foundation/session-desktop/actions/runs/$RUN_ID/artifacts") - echo "response: $response" + - uses: actions/checkout@v4 + name: 'Checkout Session desktop' + with: + repository: ${{ github.event.inputs.SESSION_DESKTOP_REPO }} + ref: ${{ github.event.inputs.BRANCH_TO_CHECKOUT_SESSION }} + path: 'desktop' - artifact_url=$(echo "$response" | jq -r \ - --arg name "$ARTIFACT_NAME" \ - '.artifacts[] | select(.name == $name) | .archive_download_url') + # Note: caching is breaking things up (app doesn't start) + # - name: Calculate desktop cache key + # run: | + # echo "CACHE_KEY=${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('desktop/package.json', 'desktop/yarn.lock', 'desktop/patches/**') }}" >> $GITHUB_ENV + - name: Install node + uses: actions/setup-node@v3 + with: + node-version-file: 'desktop/.nvmrc' - echo "Session desktop Artifact URL: $artifact_url" + - uses: actions/setup-python@v4 + with: + python-version: '3.12' - curl -L \ - -H "Authorization: token $PAT_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -o artifact.zip \ - $artifact_url + - name: Install setuptools for python 3.12 + shell: bash + run: python -m pip install --upgrade pip setuptools - unzip artifact.zip + # Note: caching is breaking things up (app doesn't start) + # - uses: actions/cache/restore@v4 + # id: cache-desktop-modules + # with: + # path: ${{ env.DESKTOP_CACHED_FOLDER }} + # key: ${{ env.CACHE_KEY }} - - name: 'print files' + - name: Install yarn run: | - ls -l + npm install -g yarn - - name: Install node - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' + - name: List desktop folder + run: | + pwd + ls -la desktop - - name: Install yarn + - name: List playwright folder run: | - npm install -g yarn + pwd + ls -la playwright + + - name: Install desktop dependencies + shell: bash + # if: steps.cache-desktop-modules.outputs.cache-hit != 'true' + run: cd $GITHUB_WORKSPACE/desktop && yarn install --frozen-lockfile --network-timeout 600000 + + # Note: caching is breaking things up (app doesn't start) + # - uses: actions/cache/save@v4 + # if: always() + # with: + # path: ${{ env.DESKTOP_CACHED_FOLDER }} + # key: ${{ env.CACHE_KEY }} + + - name: Build desktop + shell: bash + run: cd $GITHUB_WORKSPACE/desktop && yarn build-everything - - name: Install dependencies + - name: Install playwright dependencies run: | - yarn install --frozen-lockfile + cd $GITHUB_WORKSPACE/playwright && yarn install --frozen-lockfile - name: Build the Desktop tests run: | - cd $GITHUB_WORKSPACE + cd $GITHUB_WORKSPACE/playwright yarn tsc - name: Run the Desktop tests run: | - DEBUG="pw:*" PRINT_ONGOING_TESTS=1 SESSION_DESKTOP_ROOT=$GITHUB_WORKSPACE/desktop nice ionice xvfb-run --auto-servernum --server-num=1 --server-args='-screen 0, 1920x1080x24' yarn test + cd $GITHUB_WORKSPACE/playwright + SESSION_DESKTOP_ROOT=$GITHUB_WORKSPACE/desktop nice ionice xvfb-run --auto-servernum --server-num=1 --server-args='-screen 0, 1920x1080x24' yarn test # DEBUG="pw:*" - name: Kill all running electron app diff --git a/screenshots/Change-avatar/avatar-updated-blue-darwin.jpeg b/screenshots/Change-avatar/avatar-updated-blue-darwin.jpeg deleted file mode 100644 index 760290c..0000000 --- a/screenshots/Change-avatar/avatar-updated-blue-darwin.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c024420487aa28c02e16597a361c5135476ece72b216d5c507f1fc2b902b99b2 -size 1701 diff --git a/screenshots/Profile-picture-syncs/avatar-updated-blue-darwin.jpeg b/screenshots/Profile-picture-syncs/avatar-updated-blue-darwin.jpeg deleted file mode 100644 index b37f10f..0000000 --- a/screenshots/Profile-picture-syncs/avatar-updated-blue-darwin.jpeg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f966cb63def91347061c97508d9e3ac3b12693126154a0625345e06d2200985 -size 934 diff --git a/screenshots/landing-page-states/new-account-darwin.png b/screenshots/landing-page-states/new-account-darwin.png deleted file mode 100644 index dffacc0..0000000 --- a/screenshots/landing-page-states/new-account-darwin.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c9b5a06d6b4a00e5ac33dafed5434156da827814554596a0b4156c8a6b114a43 -size 41680 diff --git a/screenshots/landing-page-states/restored-account-darwin.png b/screenshots/landing-page-states/restored-account-darwin.png deleted file mode 100644 index b45cf1d..0000000 --- a/screenshots/landing-page-states/restored-account-darwin.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3d47c60f02ab86eb10129f19e6929d94172b6ff426a8e31de696b6ecca05ae78 -size 21376 diff --git a/tests/automation/create_user.spec.ts b/tests/automation/create_user.spec.ts index 49ec0c0..cebc6a9 100644 --- a/tests/automation/create_user.spec.ts +++ b/tests/automation/create_user.spec.ts @@ -14,8 +14,8 @@ sessionTestOneWindow('Create User', async ([window]) => { await sleepFor(100, true); // check username matches await waitForTestIdWithText(window, 'your-profile-name', userA.userName); - // check session id matches - await waitForTestIdWithText(window, 'your-session-id', userA.accountid); + // check Account ID matches + await waitForTestIdWithText(window, 'your-account-id', userA.accountid); // exit profile modal await clickOnTestIdWithText(window, 'modal-close-button'); // go to settings section diff --git a/tests/automation/disappearing_message_checks.spec.ts b/tests/automation/disappearing_message_checks.spec.ts index d973465..2b52653 100644 --- a/tests/automation/disappearing_message_checks.spec.ts +++ b/tests/automation/disappearing_message_checks.spec.ts @@ -237,7 +237,7 @@ test_Alice_1W_Bob_1W( // To stop the layout shift await sleepFor(500); await clickOnTestIdWithText(aliceWindow1, 'conversation-options-avatar'); - await clickOnTestIdWithText(aliceWindow1, 'add-user-button'); + await clickOnTestIdWithText(aliceWindow1, 'invite-contacts-menu-option'); await waitForTestIdWithText( aliceWindow1, 'modal-heading', diff --git a/tests/automation/disappearing_messages.spec.ts b/tests/automation/disappearing_messages.spec.ts index d1132a7..e5632fe 100644 --- a/tests/automation/disappearing_messages.spec.ts +++ b/tests/automation/disappearing_messages.spec.ts @@ -311,7 +311,7 @@ test_Alice_2W_Bob_1W( await clickOnElement({ window: aliceWindow1, strategy: 'data-testid', - selector: 'disappearing-messages', + selector: 'disappearing-messages-menu-option', maxWait: 100, }); await clickOnElement({ diff --git a/tests/automation/enforce_localized_str.spec.ts b/tests/automation/enforce_localized_str.spec.ts index ce8423c..342c60f 100644 --- a/tests/automation/enforce_localized_str.spec.ts +++ b/tests/automation/enforce_localized_str.spec.ts @@ -202,8 +202,6 @@ function getExpectedStringFromKey( return 'Your IP is visible to your call partner and a Session Technology Foundation server while using beta calls.'; case 'blockDescription': return 'Are you sure you want to block {name}? Blocked users cannot send you message requests, group invites or call you.'; - case 'conversationsDeleteDescription': - return 'Are you sure you want to delete your conversation with {name}? New messages from {name} will start a new conversation.'; case 'noteToSelfHide': return 'Hide Note to Self'; case 'noteToSelfHideDescription': @@ -236,6 +234,14 @@ function getExpectedStringFromKey( return 'View QR'; case 'recoveryPasswordView': return 'View Password'; + case 'deleteConversationDescription': + return 'Are you sure you want to delete your conversation with {name}? This will permanently delete all messages and attachments.'; + case 'manageMembers': + return 'Manage Members'; + case 'recoveryPasswordHidePermanentlyDescription1': + return 'Without your recovery password, you cannot load your account on new devices. We strongly recommend you save your recovery password in a safe and secure place before continuing.'; + case 'recoveryPasswordHidePermanentlyDescription2': + return 'Are you sure you want to permanently hide your recovery password on this device? This cannot be undone.'; default: // returning nul means we don't have an expected string yet for this key. // This will make the test fail diff --git a/tests/automation/group_testing.spec.ts b/tests/automation/group_testing.spec.ts index 8372089..d2103c8 100644 --- a/tests/automation/group_testing.spec.ts +++ b/tests/automation/group_testing.spec.ts @@ -75,7 +75,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W_Dracula_1W( await clickOnElement({ window: aliceWindow1, strategy: 'data-testid', - selector: 'add-user-button', + selector: 'invite-contacts-menu-option', }); // Waiting for animation of right panel to appear await sleepFor(1000); @@ -140,8 +140,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( // Click on edit group name await clickOnTestIdWithText(aliceWindow1, 'conversation-options-avatar'); await clickOnTestIdWithText(aliceWindow1, 'edit-group-name'); - await typeIntoInput(aliceWindow1, 'group-name-input', ' '); - await aliceWindow1.keyboard.press('Enter'); + await clickOnTestIdWithText(aliceWindow1, 'clear-group-info-name-button'); await waitForTestIdWithText(aliceWindow1, 'error-message'); const actualError = await grabTextFromElement( aliceWindow1, @@ -157,10 +156,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( aliceWindow1, englishStrippedStr('cancel').toString(), ); - await clickOnTestIdWithText( - aliceWindow1, - 'back-button-conversation-options', - ); + await clickOnTestIdWithText(aliceWindow1, 'modal-close-button'); }, ); diff --git a/tests/automation/input_validations.spec.ts b/tests/automation/input_validations.spec.ts index 13bed22..1d015ea 100644 --- a/tests/automation/input_validations.spec.ts +++ b/tests/automation/input_validations.spec.ts @@ -38,11 +38,11 @@ import { await clickOnTestIdWithText(window, 'existing-account-button'); await typeIntoInput(window, 'recovery-phrase-input', incorrectSeed); await clickOnTestIdWithText(window, 'continue-button'); - await waitForTestIdWithText(window, 'session-error-message'); + await waitForTestIdWithText(window, 'error-message'); const actualError = await grabTextFromElement( window, 'data-testid', - 'session-error-message', + 'error-message', ); if (actualError !== expectedError) { throw new Error( @@ -74,11 +74,11 @@ import { await clickOnTestIdWithText(window, 'create-account-button'); await typeIntoInput(window, 'display-name-input', displayName); await clickOnTestIdWithText(window, 'continue-button'); - await waitForTestIdWithText(window, 'session-error-message'); + await waitForTestIdWithText(window, 'error-message'); const actualError = await grabTextFromElement( window, 'data-testid', - 'session-error-message', + 'error-message', ); if (testName === 'No name') { console.log('Expected failure: see SES-2832'); diff --git a/tests/automation/landing_page.spec.ts b/tests/automation/landing_page.spec.ts index b1ac53e..f621ff0 100644 --- a/tests/automation/landing_page.spec.ts +++ b/tests/automation/landing_page.spec.ts @@ -3,6 +3,12 @@ import { compareScreenshot, waitForElement } from './utilities/utils'; export type ElementState = 'new-account' | 'restored-account'; +// TODO: Normalize screenshot dimensions before comparison to handle different pixel densities (e.g. with sharp) +// This would fix MacBook Retina (2x) vs M4 Mac Mini (1x) pixel density differences (1000x1584 vs 500x792) +// Alternatives: +// - Try to set deviceScaleFactor: 1 in Playwright context to force consistent scaling +// - Record pixel density dependent screenshots + test_Alice_2W( `Landing page states`, async ({ aliceWindow1, aliceWindow2 }, testInfo) => { diff --git a/tests/automation/linked_device_group.spec.ts b/tests/automation/linked_device_group.spec.ts index 64ce72f..da8dd8a 100644 --- a/tests/automation/linked_device_group.spec.ts +++ b/tests/automation/linked_device_group.spec.ts @@ -106,12 +106,12 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( // Check for group members await clickOnTestIdWithText(aliceWindow2, 'conversation-options-avatar'); // Check right panel has correct name - await waitForTestIdWithText(aliceWindow2, 'right-panel-group-name'); - await clickOnTestIdWithText(aliceWindow2, 'group-members'); + await waitForTestIdWithText(aliceWindow2, 'group-name'); + await clickOnTestIdWithText(aliceWindow2, 'manage-members-menu-option'); await waitForTestIdWithText( aliceWindow2, 'modal-heading', - englishStrippedStr('groupMembers').toString(), + englishStrippedStr('manageMembers').toString(), ); // Check for You, Bob and Charlie await Promise.all([ @@ -181,7 +181,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( ); // Check for group members await clickOnTestIdWithText(aliceWindow2, 'conversation-options-avatar'); - await clickOnTestIdWithText(aliceWindow2, 'group-members'); + await clickOnTestIdWithText(aliceWindow2, 'manage-members-menu-option'); // Check for You, Bob and Charlie await Promise.all([ waitForTestIdWithText( @@ -193,6 +193,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( waitForTestIdWithText(aliceWindow2, 'contact', charlie.userName), ]); await clickOnTestIdWithText(aliceWindow2, 'session-confirm-cancel-button'); + await clickOnTestIdWithText(aliceWindow2, 'modal-close-button'); // Delete device data on alicewindow2 await clearDataOnWindow(aliceWindow2); const [restoredWindow] = await openApp(1); @@ -217,7 +218,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( ); // Check for group members await clickOnTestIdWithText(restoredWindow, 'conversation-options-avatar'); - await clickOnTestIdWithText(restoredWindow, 'group-members'); + await clickOnTestIdWithText(restoredWindow, 'manage-members-menu-option'); // Check for You, Bob and Charlie await Promise.all([ waitForTestIdWithText( @@ -233,6 +234,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( restoredWindow, 'session-confirm-cancel-button', ); + await clickOnTestIdWithText(restoredWindow, 'modal-close-button'); // Delete device data on restoredWindow await clearDataOnWindow(restoredWindow); const [restoredWindow2] = await openApp(1); @@ -257,7 +259,7 @@ test_group_Alice_1W_Bob_1W_Charlie_1W( ); // Check for group members await clickOnTestIdWithText(restoredWindow2, 'conversation-options-avatar'); - await clickOnTestIdWithText(restoredWindow2, 'group-members'); + await clickOnTestIdWithText(restoredWindow2, 'manage-members-menu-option'); // Check for You, Bob and Charlie await Promise.all([ waitForTestIdWithText( diff --git a/tests/automation/linked_device_user.spec.ts b/tests/automation/linked_device_user.spec.ts index f96d32b..184e416 100644 --- a/tests/automation/linked_device_user.spec.ts +++ b/tests/automation/linked_device_user.spec.ts @@ -41,10 +41,10 @@ sessionTestOneWindow('Link a device', async ([aliceWindow1]) => { 'your-profile-name', userA.userName, ); - // Verify Session ID + // Verify Account ID await waitForTestIdWithText( aliceWindow1, - 'your-session-id', + 'your-account-id', userA.accountid, ); // exit profile modal @@ -161,7 +161,7 @@ test_Alice_2W( }); // This file is saved in `Profile-picture-syncs` folder expect(screenshot).toMatchSnapshot({ - name: 'avatar-updated-blue.jpeg', + name: `avatar-updated-blue.jpeg`, }); correctScreenshot = true; console.info( @@ -407,7 +407,7 @@ test_Alice_2W_Bob_1W( await checkModalStrings( aliceWindow1, englishStrippedStr('conversationsDelete').toString(), - englishStrippedStr('conversationsDeleteDescription') + englishStrippedStr('deleteConversationDescription') .withArgs({ name: bob.userName }) .toString(), ); @@ -501,7 +501,7 @@ test_Alice_2W( aliceWindow2, 'data-testid', 'module-conversation__user__profile-name', - 8000, + 10000, englishStrippedStr('noteToSelf').toString(), ), ]); diff --git a/tests/automation/message_checks.spec.ts b/tests/automation/message_checks.spec.ts index 5649f6d..425d46e 100644 --- a/tests/automation/message_checks.spec.ts +++ b/tests/automation/message_checks.spec.ts @@ -122,7 +122,7 @@ test_Alice_1W_Bob_1W( await createContact(aliceWindow1, bobWindow1, alice, bob); await joinCommunity(aliceWindow1); await clickOnTestIdWithText(aliceWindow1, 'conversation-options-avatar'); - await clickOnTestIdWithText(aliceWindow1, 'add-user-button'); + await clickOnTestIdWithText(aliceWindow1, 'invite-contacts-menu-option'); await waitForTestIdWithText( aliceWindow1, 'modal-heading', diff --git a/tests/automation/setup/new_user.ts b/tests/automation/setup/new_user.ts index 3ebaa8d..5653922 100644 --- a/tests/automation/setup/new_user.ts +++ b/tests/automation/setup/new_user.ts @@ -33,9 +33,9 @@ export const newUser = async ( // await clickOnTestIdWithText(window, 'modal-close-button'); await clickOnTestIdWithText(window, 'leftpane-primary-avatar'); - // Save session ID to a variable - let accountid = await window.innerText('[data-testid=your-session-id]'); - accountid = accountid.replace(/(\r\n|\n|\r)/gm, ''); // remove the new line in the SessionID as it is rendered with one forced + // Save Account ID to a variable + let accountid = await window.innerText('[data-testid=your-account-id]'); + accountid = accountid.replace(/(\r\n|\n|\r)/gm, ''); // remove the new line in the Account ID as it is rendered with one forced console.log( `${userName}: Account ID: "${chalk.blue( diff --git a/tests/automation/setup/open.ts b/tests/automation/setup/open.ts index 3cb87e5..7431a2f 100644 --- a/tests/automation/setup/open.ts +++ b/tests/automation/setup/open.ts @@ -26,20 +26,20 @@ const openElectronAppOnly = async (multi: string) => { process.env.NODE_ENV = NODE_ENV; process.env.SESSION_DEBUG = '1'; - if (!isEmpty(process.env.CI)) { - const sessionBinPath = './session-desktop-linux-x86_64-1.16.2.AppImage'; - const fakeHome = `/tmp/${process.env.NODE_APP_INSTANCE}`; + // if (!isEmpty(process.env.CI)) { + // const sessionBinPath = getSessionDesktopBinPath(); + // const fakeHome = `/tmp/${process.env.NODE_APP_INSTANCE}`; - console.info(` CI RUN`); - console.info(` SESSION_BIN_PATH=${sessionBinPath}`); - console.info(` HOME="${fakeHome}"`); + // console.info(` CI RUN`); + // console.info(` SESSION_BIN_PATH=${sessionBinPath}`); + // console.info(` HOME="${fakeHome}"`); - process.env.HOME = fakeHome; + // process.env.HOME = fakeHome; - return electron.launch({ - executablePath: sessionBinPath, - }); - } + // return electron.launch({ + // executablePath: sessionBinPath, + // }); + // } console.info(` NON CI RUN`); console.info(' NODE_ENV', process.env.NODE_ENV); console.info(' NODE_APP_INSTANCE', process.env.NODE_APP_INSTANCE); diff --git a/tests/automation/types/testing.ts b/tests/automation/types/testing.ts index 86ecd47..7b13d09 100644 --- a/tests/automation/types/testing.ts +++ b/tests/automation/types/testing.ts @@ -77,6 +77,7 @@ export type MediaType = 'image' | 'video' | 'audio' | 'file'; export type Strategy = 'data-testid' | 'class' | ':has-text'; // Would be good to find a way to sort those with prettier +// TODO sort with eslint plugin perfectionist export type DataTestId = | 'session-id-signup' | 'display-name-input' @@ -89,7 +90,6 @@ export type DataTestId = | 'control-message' | 'disappear-control-message' | 'disappearing-messages-indicator' - | 'back-button-conversation-options' | 'conversation-options-avatar' | 'settings-section' | 'clear-data-settings-menu-item' @@ -107,7 +107,7 @@ export type DataTestId = | 'disappearing-messages-dropdown' | 'session-toast' | 'accept-message-request' - | 'confirm-nickname' + | 'set-nickname-confirm-button' | 'nickname-input' | 'three-dots-conversation-options' | 'message-section' @@ -142,22 +142,20 @@ export type DataTestId = | 'new-closed-group-name' | 'create-group-button' | 'link-device' - | 'group-name-input' - | 'right-panel-group-name' + | 'update-group-info-name-input' + | 'group-name' | 'header-conversation-name' | 'copy-button-profile-update' | 'loading-spinner' | 'empty-conversation-notification' | 'your-profile-name' - | 'your-session-id' | 'mentions-popup-row' | 'enable-read-receipts' | 'disappear-set-button' | 'disappear-after-read-option' - | 'disappearing-messages' + | 'disappearing-messages-menu-option' | 'disappear-after-send-option' | 'disappear-set-button' - | 'add-user-button' | 'message-content' | 'group-update-message' | 'message-request-response-message' @@ -168,7 +166,6 @@ export type DataTestId = | 'existing-account-button' | 'context-menu-item' | 'modal-description' - | 'session-error-message' | DMTimeOption | `input-${DMTimeOption}` | 'disappear-messages-type-and-time' @@ -189,6 +186,8 @@ export type DataTestId = | 'link-preview-image' | 'link-preview-title' | 'error-message' - | 'group-members' + | 'manage-members-menu-option' | 'session-confirm-cancel-button' - | 'session-recovery-password'; + | 'session-recovery-password' + | 'invite-contacts-menu-option' + | 'clear-group-info-name-button'; \ No newline at end of file diff --git a/tests/automation/user_actions.spec.ts b/tests/automation/user_actions.spec.ts index 6b6f438..8bcd3a7 100644 --- a/tests/automation/user_actions.spec.ts +++ b/tests/automation/user_actions.spec.ts @@ -162,6 +162,12 @@ test_Alice_1W_no_network('Change username', async ({ aliceWindow1 }) => { await clickOnTestIdWithText(aliceWindow1, 'modal-close-button'); }); +// TODO: Normalize screenshot dimensions before comparison to handle different pixel densities (e.g. with sharp) +// This would fix MacBook Retina (2x) vs M4 Mac Mini (1x) pixel density differences (56x56 vs 28x28) +// Alternatives: +// - Try to set deviceScaleFactor: 1 in Playwright context to force consistent scaling +// - Record pixel density dependent screenshots + test_Alice_1W_no_network( 'Change avatar', async ({ aliceWindow1 }, testInfo) => { @@ -248,7 +254,7 @@ test_Alice_1W_Bob_1W( await sleepFor(100); await clickOnTestIdWithText( aliceWindow1, - 'confirm-nickname', + 'set-nickname-confirm-button', englishStrippedStr('save').toString(), ); await sleepFor(1000); @@ -370,7 +376,7 @@ test_Alice_1W_Bob_1W( await checkModalStrings( aliceWindow1, englishStrippedStr('conversationsDelete').toString(), - englishStrippedStr('conversationsDeleteDescription') + englishStrippedStr('deleteConversationDescription') .withArgs({ name: bob.userName }) .toString(), ); diff --git a/tests/automation/utilities/rename_group.ts b/tests/automation/utilities/rename_group.ts index 7977d21..741e1e7 100644 --- a/tests/automation/utilities/rename_group.ts +++ b/tests/automation/utilities/rename_group.ts @@ -16,11 +16,11 @@ export const renameGroup = async ( await clickOnMatchingText(window, oldGroupName); await clickOnTestIdWithText(window, 'conversation-options-avatar'); await clickOnTestIdWithText(window, 'edit-group-name'); - await typeIntoInput(window, 'group-name-input', newGroupName); + await typeIntoInput(window, 'update-group-info-name-input', newGroupName); await window.keyboard.press('Enter'); - await clickOnMatchingText(window, englishStrippedStr('okay').toString()); - await waitForTestIdWithText(window, 'right-panel-group-name', newGroupName); - await clickOnTestIdWithText(window, 'back-button-conversation-options'); + await clickOnMatchingText(window, englishStrippedStr('save').toString()); + await waitForTestIdWithText(window, 'group-name', newGroupName); + await clickOnTestIdWithText(window, 'modal-close-button'); // Check config message await waitForMatchingText( window, diff --git a/tests/automation/utilities/set_disappearing_messages.ts b/tests/automation/utilities/set_disappearing_messages.ts index df1fd41..b62e7ee 100644 --- a/tests/automation/utilities/set_disappearing_messages.ts +++ b/tests/automation/utilities/set_disappearing_messages.ts @@ -39,7 +39,7 @@ export const setDisappearingMessages = async ( await clickOnElement({ window: windowA, strategy: 'data-testid', - selector: 'disappearing-messages', + selector: 'disappearing-messages-menu-option', maxWait: 100, }); return true; @@ -97,6 +97,11 @@ export const setDisappearingMessages = async ( strategy: 'data-testid', selector: 'disappear-set-button', }); + await clickOnElement({ + window: windowA, + strategy: 'data-testid', + selector: 'modal-close-button', + }); await waitForTestIdWithText(windowA, 'disappear-messages-type-and-time'); if (windowB) { await clickOnMatchingText( diff --git a/tests/localization/Localizer.ts b/tests/localization/Localizer.ts index c231d5d..7b3ad67 100644 --- a/tests/localization/Localizer.ts +++ b/tests/localization/Localizer.ts @@ -170,10 +170,15 @@ class LocalizedStringBuilder extends String { return this; } - private postProcessStrippedString(str: string): string { - const strippedString = str.replaceAll(/<[^>]*>/g, ''); - return deSanitizeHtmlTags(strippedString, '\u200B'); - } +private postProcessStrippedString(str: string): string { + // Normalize whitespace around
tags: + // "

" and "
" both become a single space + let strippedString = str.replace(/\s*([\s]*)+/gi, ' '); + // Then, remove all other HTML tags + strippedString = strippedString.replace(/<[^>]*>/g, ''); + + return deSanitizeHtmlTags(strippedString, '\u200B'); +} private localeToTarget(): CrowdinLocale { return this.isEnglishForced ? 'en' : this.crowdinLocale; diff --git a/tests/localization/constants.ts b/tests/localization/constants.ts index 8ade63e..fd7dc29 100644 --- a/tests/localization/constants.ts +++ b/tests/localization/constants.ts @@ -3,14 +3,23 @@ export enum LOCALE_DEFAULTS { session_download_url = 'https://getsession.org/download', gif = 'GIF', oxen_foundation = 'Oxen Foundation', + network_name = 'Session Network', + token_name_long = 'Session Token', + staking_reward_pool = 'Staking Reward Pool', + token_name_short = 'SESH', + usd_name_short = 'USD', + app_pro = 'Session Pro', } export const rtlLocales = ['ar', 'fa', 'he', 'ps', 'ur']; -export const crowdinLocales = ['en'] as const; +export const crowdinLocales = [ + 'en', +] as const; export type CrowdinLocale = (typeof crowdinLocales)[number]; export function isCrowdinLocale(locale: string): locale is CrowdinLocale { return crowdinLocales.includes(locale as CrowdinLocale); } + diff --git a/tests/localization/locales.ts b/tests/localization/locales.ts index 3675fcc..b538d48 100644 --- a/tests/localization/locales.ts +++ b/tests/localization/locales.ts @@ -1,3528 +1,3776 @@ + // This file was generated by a script. Do not modify this file manually. // To make changes, modify the corresponding JSON file and re-run the script. + export const simpleDictionary = { about: { - en: 'About', - args: undefined, + en: "About", + args: undefined, }, accept: { - en: 'Accept', - args: undefined, + en: "Accept", + args: undefined, }, accountIDCopy: { - en: 'Copy Account ID', - args: undefined, + en: "Copy Account ID", + args: undefined, + }, + accountId: { + en: "Account ID", + args: undefined, }, accountIdCopied: { - en: 'Account ID Copied', - args: undefined, + en: "Account ID Copied", + args: undefined, }, accountIdCopyDescription: { - en: 'Copy your Account ID then share it with your friends so they can message you.', - args: undefined, + en: "Copy your Account ID then share it with your friends so they can message you.", + args: undefined, }, accountIdEnter: { - en: 'Enter Account ID', - args: undefined, + en: "Enter Account ID", + args: undefined, }, accountIdErrorInvalid: { - en: 'This Account ID is invalid. Please check and try again.', - args: undefined, + en: "This Account ID is invalid. Please check and try again.", + args: undefined, }, accountIdOrOnsEnter: { - en: 'Enter Account ID or ONS', - args: undefined, + en: "Enter Account ID or ONS", + args: undefined, }, accountIdOrOnsInvite: { - en: 'Invite Account ID or ONS', - args: undefined, + en: "Invite Account ID or ONS", + args: undefined, }, accountIdShare: { - en: "Hey, I've been using Session to chat with complete privacy and security. Come join me! My Account ID is

{account_id}

Download it at https://getsession.org/download", - args: { account_id: 'string' }, + en: "Hey, I've been using Session to chat with complete privacy and security. Come join me! My Account ID is

{account_id}

Download it at https://getsession.org/download", + args: {account_id: "string"} }, accountIdYours: { - en: 'Your Account ID', - args: undefined, + en: "Your Account ID", + args: undefined, }, accountIdYoursDescription: { - en: 'This is your Account ID. Other users can scan it to start a conversation with you.', - args: undefined, + en: "This is your Account ID. Other users can scan it to start a conversation with you.", + args: undefined, }, actualSize: { - en: 'Actual Size', - args: undefined, + en: "Actual Size", + args: undefined, }, add: { - en: 'Add', - args: undefined, + en: "Add", + args: undefined, + }, + addAdmins: { + en: "Add Admins", + args: undefined, + }, + addAdminsDescription: { + en: "Enter the Account ID of the user you are promoting to admin.

To add multiple users, enter each Account ID separated by a comma. Up to 20 Account IDs can be specified at a time.", + args: undefined, }, adminCannotBeRemoved: { - en: 'Admins cannot be removed.', - args: undefined, + en: "Admins cannot be removed.", + args: undefined, }, adminMorePromotedToAdmin: { - en: '{name} and {count} others were promoted to Admin.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others were promoted to Admin.", + args: {name: "string", count: "number"} }, adminPromote: { - en: 'Promote Admins', - args: undefined, + en: "Promote Admins", + args: undefined, }, adminPromoteDescription: { - en: 'Are you sure you want to promote {name} to admin? Admins cannot be removed.', - args: { name: 'string' }, + en: "Are you sure you want to promote {name} to admin? Admins cannot be removed.", + args: {name: "string"} }, adminPromoteMoreDescription: { - en: 'Are you sure you want to promote {name} and {count} others to admin? Admins cannot be removed.', - args: { name: 'string', count: 'number' }, + en: "Are you sure you want to promote {name} and {count} others to admin? Admins cannot be removed.", + args: {name: "string", count: "number"} }, adminPromoteToAdmin: { - en: 'Promote to Admin', - args: undefined, + en: "Promote to Admin", + args: undefined, }, adminPromoteTwoDescription: { - en: 'Are you sure you want to promote {name} and {other_name} to admin? Admins cannot be removed.', - args: { name: 'string', other_name: 'string' }, + en: "Are you sure you want to promote {name} and {other_name} to admin? Admins cannot be removed.", + args: {name: "string", other_name: "string"} }, adminPromotedToAdmin: { - en: '{name} was promoted to Admin.', - args: { name: 'string' }, + en: "{name} was promoted to Admin.", + args: {name: "string"} }, adminPromotionFailed: { - en: 'Admin promotion failed', - args: undefined, + en: "Admin promotion failed", + args: undefined, }, adminPromotionFailedDescription: { - en: 'Failed to promote {name} in {group_name}', - args: { name: 'string', group_name: 'string' }, + en: "Failed to promote {name} in {group_name}", + args: {name: "string", group_name: "string"} }, adminPromotionFailedDescriptionMultiple: { - en: 'Failed to promote {name} and {count} others in {group_name}', - args: { name: 'string', count: 'number', group_name: 'string' }, + en: "Failed to promote {name} and {count} others in {group_name}", + args: {name: "string", count: "number", group_name: "string"} }, adminPromotionFailedDescriptionTwo: { - en: 'Failed to promote {name} and {other_name} in {group_name}', - args: { name: 'string', other_name: 'string', group_name: 'string' }, + en: "Failed to promote {name} and {other_name} in {group_name}", + args: {name: "string", other_name: "string", group_name: "string"} }, adminPromotionNotSent: { - en: 'Promotion not sent', - args: undefined, + en: "Promotion not sent", + args: undefined, }, adminPromotionSent: { - en: 'Admin promotion sent', - args: undefined, + en: "Admin promotion sent", + args: undefined, }, adminPromotionStatusUnknown: { - en: 'Promotion status unknown', - args: undefined, + en: "Promotion status unknown", + args: undefined, }, adminRemove: { - en: 'Remove Admins', - args: undefined, + en: "Remove Admins", + args: undefined, }, adminRemoveAsAdmin: { - en: 'Remove as Admin', - args: undefined, + en: "Remove as Admin", + args: undefined, }, adminRemoveCommunityNone: { - en: 'There are no Admins in this Community.', - args: undefined, + en: "There are no Admins in this Community.", + args: undefined, }, adminRemoveFailed: { - en: 'Failed to remove {name} as Admin.', - args: { name: 'string' }, + en: "Failed to remove {name} as Admin.", + args: {name: "string"} }, adminRemoveFailedMultiple: { - en: 'Failed to remove {name} and {count} others as Admin.', - args: { name: 'string', count: 'number' }, + en: "Failed to remove {name} and {count} others as Admin.", + args: {name: "string", count: "number"} }, adminRemoveFailedOther: { - en: 'Failed to remove {name} and {other_name} as Admin.', - args: { name: 'string', other_name: 'string' }, + en: "Failed to remove {name} and {other_name} as Admin.", + args: {name: "string", other_name: "string"} }, adminRemovedUser: { - en: '{name} was removed as Admin.', - args: { name: 'string' }, + en: "{name} was removed as Admin.", + args: {name: "string"} }, adminRemovedUserMultiple: { - en: '{name} and {count} others were removed as Admin.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others were removed as Admin.", + args: {name: "string", count: "number"} }, adminRemovedUserOther: { - en: '{name} and {other_name} were removed as Admin.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} were removed as Admin.", + args: {name: "string", other_name: "string"} }, adminSettings: { - en: 'Admin Settings', - args: undefined, + en: "Admin Settings", + args: undefined, }, adminTwoPromotedToAdmin: { - en: '{name} and {other_name} were promoted to Admin.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} were promoted to Admin.", + args: {name: "string", other_name: "string"} }, andMore: { - en: '+{count}', - args: { count: 'number' }, + en: "+{count}", + args: {count: "number"} }, anonymous: { - en: 'Anonymous', - args: undefined, + en: "Anonymous", + args: undefined, }, appIcon: { - en: 'App Icon', - args: undefined, + en: "App Icon", + args: undefined, + }, + appIconAndNameChange: { + en: "Change App Icon and Name", + args: undefined, + }, + appIconAndNameChangeConfirmation: { + en: "Changing the app icon and name requires Session to be closed. Notifications will continue to use the default Session icon and name.", + args: undefined, }, appIconAndNameDescription: { - en: 'Alternate app icon and name is displayed on home screen and app drawer.', - args: undefined, + en: "Alternate app icon and name is displayed on home screen and app drawer.", + args: undefined, + }, + appIconAndNameSelectionDescription: { + en: "The selected app icon and name is displayed on the home screen and app drawer.", + args: undefined, }, appIconAndNameSelectionTitle: { - en: 'Icon and name', - args: undefined, + en: "Icon and name", + args: undefined, }, appIconDescription: { - en: "Alternate app icon is displayed on home screen and app library. App name will still appear as 'Session'.", - args: undefined, + en: "Alternate app icon is displayed on home screen and app library. App name will still appear as 'Session'.", + args: undefined, }, appIconEnableIcon: { - en: 'Use alternate app icon', - args: undefined, + en: "Use alternate app icon", + args: undefined, }, appIconEnableIconAndName: { - en: 'Use alternate app icon and name', - args: undefined, + en: "Use alternate app icon and name", + args: undefined, }, appIconSelect: { - en: 'Select alternate app icon', - args: undefined, + en: "Select alternate app icon", + args: undefined, }, appIconSelectionTitle: { - en: 'Icon', - args: undefined, + en: "Icon", + args: undefined, }, appNameCalculator: { - en: 'Calculator', - args: undefined, + en: "Calculator", + args: undefined, }, appNameMeetingSE: { - en: 'MeetingSE', - args: undefined, + en: "MeetingSE", + args: undefined, }, appNameNews: { - en: 'News', - args: undefined, + en: "News", + args: undefined, }, appNameNotes: { - en: 'Notes', - args: undefined, + en: "Notes", + args: undefined, }, appNameStocks: { - en: 'Stocks', - args: undefined, + en: "Stocks", + args: undefined, }, appNameWeather: { - en: 'Weather', - args: undefined, + en: "Weather", + args: undefined, }, appearanceAutoDarkMode: { - en: 'Auto dark-mode', - args: undefined, + en: "Auto dark-mode", + args: undefined, }, appearanceHideMenuBar: { - en: 'Hide Menu Bar', - args: undefined, + en: "Hide Menu Bar", + args: undefined, }, appearanceLanguage: { - en: 'Language', - args: undefined, + en: "Language", + args: undefined, }, appearanceLanguageDescription: { - en: 'Choose your language setting for Session. Session will restart when you change your language setting.', - args: undefined, + en: "Choose your language setting for Session. Session will restart when you change your language setting.", + args: undefined, }, appearancePreview1: { - en: 'How are you?', - args: undefined, + en: "How are you?", + args: undefined, }, appearancePreview2: { - en: "I'm good thanks, you?", - args: undefined, + en: "I'm good thanks, you?", + args: undefined, }, appearancePreview3: { - en: "I'm doing great, thanks.", - args: undefined, + en: "I'm doing great, thanks.", + args: undefined, }, appearancePrimaryColor: { - en: 'Primary Color', - args: undefined, + en: "Primary Color", + args: undefined, }, appearanceThemes: { - en: 'Themes', - args: undefined, + en: "Themes", + args: undefined, }, appearanceThemesClassicDark: { - en: 'Classic Dark', - args: undefined, + en: "Classic Dark", + args: undefined, }, appearanceThemesClassicLight: { - en: 'Classic Light', - args: undefined, + en: "Classic Light", + args: undefined, }, appearanceThemesOceanDark: { - en: 'Ocean Dark', - args: undefined, + en: "Ocean Dark", + args: undefined, }, appearanceThemesOceanLight: { - en: 'Ocean Light', - args: undefined, + en: "Ocean Light", + args: undefined, }, appearanceZoom: { - en: 'Zoom', - args: undefined, + en: "Zoom", + args: undefined, }, appearanceZoomIn: { - en: 'Zoom In', - args: undefined, + en: "Zoom In", + args: undefined, }, appearanceZoomOut: { - en: 'Zoom Out', - args: undefined, + en: "Zoom Out", + args: undefined, }, attachment: { - en: 'Attachment', - args: undefined, + en: "Attachment", + args: undefined, }, attachments: { - en: 'Attachments', - args: undefined, + en: "Attachments", + args: undefined, }, attachmentsAdd: { - en: 'Add attachment', - args: undefined, + en: "Add attachment", + args: undefined, }, attachmentsAlbumUnnamed: { - en: 'Unnamed Album', - args: undefined, + en: "Unnamed Album", + args: undefined, }, attachmentsAutoDownload: { - en: 'Auto-download Attachments', - args: undefined, + en: "Auto-download Attachments", + args: undefined, }, attachmentsAutoDownloadDescription: { - en: 'Automatically download media and files from this chat.', - args: undefined, + en: "Automatically download media and files from this chat.", + args: undefined, }, attachmentsAutoDownloadModalDescription: { - en: 'Would you like to automatically download all files from {conversation_name}?', - args: { conversation_name: 'string' }, + en: "Would you like to automatically download all files from {conversation_name}?", + args: {conversation_name: "string"} }, attachmentsAutoDownloadModalTitle: { - en: 'Auto Download', - args: undefined, + en: "Auto Download", + args: undefined, }, attachmentsClearAll: { - en: 'Clear All Attachments', - args: undefined, + en: "Clear All Attachments", + args: undefined, }, attachmentsClearAllDescription: { - en: 'Are you sure you want to clear all attachments? Messages with attachments will also be deleted.', - args: undefined, + en: "Are you sure you want to clear all attachments? Messages with attachments will also be deleted.", + args: undefined, }, attachmentsClickToDownload: { - en: 'Click to download {file_type}', - args: { file_type: 'string' }, + en: "Click to download {file_type}", + args: {file_type: "string"} }, attachmentsCollapseOptions: { - en: 'Collapse attachment options', - args: undefined, + en: "Collapse attachment options", + args: undefined, }, attachmentsCollecting: { - en: 'Collecting attachments...', - args: undefined, + en: "Collecting attachments...", + args: undefined, }, attachmentsDownload: { - en: 'Download Attachment', - args: undefined, + en: "Download Attachment", + args: undefined, }, attachmentsDuration: { - en: 'Duration:', - args: undefined, + en: "Duration:", + args: undefined, }, attachmentsErrorLoad: { - en: 'Error attaching file', - args: undefined, + en: "Error attaching file", + args: undefined, }, attachmentsErrorMediaSelection: { - en: 'Failed to select attachment', - args: undefined, + en: "Failed to select attachment", + args: undefined, }, attachmentsErrorNoApp: { - en: "Can't find an app to select media.", - args: undefined, + en: "Can't find an app to select media.", + args: undefined, }, attachmentsErrorNotSupported: { - en: 'This file type is not supported.', - args: undefined, + en: "This file type is not supported.", + args: undefined, }, attachmentsErrorNumber: { - en: 'Unable to send more than 32 image and video files at once.', - args: undefined, + en: "Unable to send more than 32 image and video files at once.", + args: undefined, }, attachmentsErrorOpen: { - en: 'Unable to open file.', - args: undefined, + en: "Unable to open file.", + args: undefined, }, attachmentsErrorSending: { - en: 'Error sending file', - args: undefined, + en: "Error sending file", + args: undefined, }, attachmentsErrorSeparate: { - en: 'Please send files as separate messages.', - args: undefined, + en: "Please send files as separate messages.", + args: undefined, }, attachmentsErrorSize: { - en: 'Files must be less than 10MB', - args: undefined, + en: "Files must be less than 10MB", + args: undefined, }, attachmentsErrorTypes: { - en: 'Cannot attach images and video with other file types. Try sending other files in a separate message.', - args: undefined, + en: "Cannot attach images and video with other file types. Try sending other files in a separate message.", + args: undefined, }, attachmentsExpired: { - en: 'Attachment expired', - args: undefined, + en: "Attachment expired", + args: undefined, }, attachmentsFileId: { - en: 'File ID:', - args: undefined, + en: "File ID:", + args: undefined, }, attachmentsFileSize: { - en: 'File Size:', - args: undefined, + en: "File Size:", + args: undefined, }, attachmentsFileType: { - en: 'File Type:', - args: undefined, + en: "File Type:", + args: undefined, }, attachmentsFilesEmpty: { - en: "You don't have any files in this conversation.", - args: undefined, + en: "You don't have any files in this conversation.", + args: undefined, }, attachmentsImageErrorMetadata: { - en: 'Unable to remove metadata from file.', - args: undefined, + en: "Unable to remove metadata from file.", + args: undefined, }, attachmentsLoadingNewer: { - en: 'Loading Newer Media...', - args: undefined, + en: "Loading Newer Media...", + args: undefined, }, attachmentsLoadingNewerFiles: { - en: 'Loading Newer Files...', - args: undefined, + en: "Loading Newer Files...", + args: undefined, }, attachmentsLoadingOlder: { - en: 'Loading Older Media...', - args: undefined, + en: "Loading Older Media...", + args: undefined, }, attachmentsLoadingOlderFiles: { - en: 'Loading Older Files...', - args: undefined, + en: "Loading Older Files...", + args: undefined, }, attachmentsMedia: { - en: '{name} on {date_time}', - args: { name: 'string', date_time: 'string' }, + en: "{name} on {date_time}", + args: {name: "string", date_time: "string"} }, attachmentsMediaEmpty: { - en: "You don't have any media in this conversation.", - args: undefined, + en: "You don't have any media in this conversation.", + args: undefined, }, attachmentsMediaSaved: { - en: 'Media saved by {name}', - args: { name: 'string' }, + en: "Media saved by {name}", + args: {name: "string"} }, attachmentsMoveAndScale: { - en: 'Move and Scale', - args: undefined, + en: "Move and Scale", + args: undefined, }, attachmentsNa: { - en: 'N/A', - args: undefined, + en: "N/A", + args: undefined, }, attachmentsNotification: { - en: '{emoji} Attachment', - args: { emoji: 'string' }, + en: "{emoji} Attachment", + args: {emoji: "string"} }, attachmentsNotificationGroup: { - en: '{author}: {emoji} Attachment', - args: { author: 'string', emoji: 'string' }, + en: "{author}: {emoji} Attachment", + args: {author: "string", emoji: "string"} }, attachmentsResolution: { - en: 'Resolution:', - args: undefined, + en: "Resolution:", + args: undefined, }, attachmentsSaveError: { - en: 'Unable to save file.', - args: undefined, + en: "Unable to save file.", + args: undefined, }, attachmentsSendTo: { - en: 'Send to {name}', - args: { name: 'string' }, + en: "Send to {name}", + args: {name: "string"} }, attachmentsTapToDownload: { - en: 'Tap to download {file_type}', - args: { file_type: 'string' }, + en: "Tap to download {file_type}", + args: {file_type: "string"} }, attachmentsThisMonth: { - en: 'This Month', - args: undefined, + en: "This Month", + args: undefined, }, attachmentsThisWeek: { - en: 'This Week', - args: undefined, + en: "This Week", + args: undefined, }, attachmentsWarning: { - en: 'Attachments you save can be accessed by other apps on your device.', - args: undefined, + en: "Attachments you save can be accessed by other apps on your device.", + args: undefined, }, audio: { - en: 'Audio', - args: undefined, + en: "Audio", + args: undefined, }, audioNoInput: { - en: 'No audio input found', - args: undefined, + en: "No audio input found", + args: undefined, }, audioNoOutput: { - en: 'No audio output found', - args: undefined, + en: "No audio output found", + args: undefined, }, audioUnableToPlay: { - en: 'Unable to play audio file.', - args: undefined, + en: "Unable to play audio file.", + args: undefined, }, audioUnableToRecord: { - en: 'Unable to record audio.', - args: undefined, + en: "Unable to record audio.", + args: undefined, }, authenticateFailed: { - en: 'Authentication Failed', - args: undefined, + en: "Authentication Failed", + args: undefined, }, authenticateFailedTooManyAttempts: { - en: 'Too many failed authentication attempts. Please try again later.', - args: undefined, + en: "Too many failed authentication attempts. Please try again later.", + args: undefined, }, authenticateNotAccessed: { - en: 'Authentication could not be accessed.', - args: undefined, + en: "Authentication could not be accessed.", + args: undefined, }, authenticateToOpen: { - en: 'Authenticate to open Session.', - args: undefined, + en: "Authenticate to open Session.", + args: undefined, }, back: { - en: 'Back', - args: undefined, + en: "Back", + args: undefined, }, banDeleteAll: { - en: 'Ban and Delete All', - args: undefined, + en: "Ban and Delete All", + args: undefined, }, banErrorFailed: { - en: 'Ban failed', - args: undefined, + en: "Ban failed", + args: undefined, }, banUnbanErrorFailed: { - en: 'Unban failed', - args: undefined, + en: "Unban failed", + args: undefined, }, banUnbanUser: { - en: 'Unban User', - args: undefined, + en: "Unban User", + args: undefined, + }, + banUnbanUserDescription: { + en: "Enter the Account ID of the user you are unbanning", + args: undefined, }, banUnbanUserUnbanned: { - en: 'User unbanned', - args: undefined, + en: "User unbanned", + args: undefined, }, banUser: { - en: 'Ban User', - args: undefined, + en: "Ban User", + args: undefined, }, banUserBanned: { - en: 'User banned', - args: undefined, + en: "User banned", + args: undefined, + }, + banUserDescription: { + en: "Enter the Account ID of the user you are banning", + args: undefined, }, block: { - en: 'Block', - args: undefined, + en: "Block", + args: undefined, }, blockBlockedDescription: { - en: 'Unblock this contact to send a message', - args: undefined, + en: "Unblock this contact to send a message", + args: undefined, }, blockBlockedNone: { - en: 'No blocked contacts', - args: undefined, + en: "No blocked contacts", + args: undefined, }, blockBlockedUser: { - en: 'Blocked {name}', - args: { name: 'string' }, + en: "Blocked {name}", + args: {name: "string"} }, blockDescription: { - en: 'Are you sure you want to block {name}? Blocked users cannot send you message requests, group invites or call you.', - args: { name: 'string' }, + en: "Are you sure you want to block {name}? Blocked users cannot send you message requests, group invites or call you.", + args: {name: "string"} }, blockUnblock: { - en: 'Unblock', - args: undefined, + en: "Unblock", + args: undefined, }, blockUnblockName: { - en: 'Are you sure you want to unblock {name}?', - args: { name: 'string' }, + en: "Are you sure you want to unblock {name}?", + args: {name: "string"} }, blockUnblockNameMultiple: { - en: 'Are you sure you want to unblock {name} and {count} others?', - args: { name: 'string', count: 'number' }, + en: "Are you sure you want to unblock {name} and {count} others?", + args: {name: "string", count: "number"} }, blockUnblockNameTwo: { - en: 'Are you sure you want to unblock {name} and 1 other?', - args: { name: 'string' }, + en: "Are you sure you want to unblock {name} and 1 other?", + args: {name: "string"} }, blockUnblockedUser: { - en: 'Unblocked {name}', - args: { name: 'string' }, + en: "Unblocked {name}", + args: {name: "string"} }, call: { - en: 'Call', - args: undefined, + en: "Call", + args: undefined, }, callsCalledYou: { - en: '{name} called you', - args: { name: 'string' }, + en: "{name} called you", + args: {name: "string"} }, callsCannotStart: { - en: 'You cannot start a new call. Finish your current call first.', - args: undefined, + en: "You cannot start a new call. Finish your current call first.", + args: undefined, }, callsConnecting: { - en: 'Connecting...', - args: undefined, + en: "Connecting...", + args: undefined, }, callsEnd: { - en: 'End call', - args: undefined, + en: "End call", + args: undefined, }, callsEnded: { - en: 'Call Ended', - args: undefined, + en: "Call Ended", + args: undefined, }, callsErrorAnswer: { - en: 'Failed to answer call', - args: undefined, + en: "Failed to answer call", + args: undefined, }, callsErrorStart: { - en: 'Failed to start call', - args: undefined, + en: "Failed to start call", + args: undefined, }, callsInProgress: { - en: 'Call in progress', - args: undefined, + en: "Call in progress", + args: undefined, }, callsIncoming: { - en: 'Incoming call from {name}', - args: { name: 'string' }, + en: "Incoming call from {name}", + args: {name: "string"} }, callsIncomingUnknown: { - en: 'Incoming call', - args: undefined, + en: "Incoming call", + args: undefined, }, callsMicrophonePermissionsRequired: { - en: "You missed a call from {name} because you haven't granted microphone access.", - args: { name: 'string' }, + en: "You missed a call from {name} because you haven't granted microphone access.", + args: {name: "string"} }, callsMissed: { - en: 'Missed Call', - args: undefined, + en: "Missed Call", + args: undefined, }, callsMissedCallFrom: { - en: 'Missed call from {name}', - args: { name: 'string' }, + en: "Missed call from {name}", + args: {name: "string"} }, callsNotificationsRequired: { - en: 'Voice and Video Calls require notifications to be enabled in your device system settings.', - args: undefined, + en: "Voice and Video Calls require notifications to be enabled in your device system settings.", + args: undefined, }, callsPermissionsRequired: { - en: 'Call Permissions Required', - args: undefined, + en: "Call Permissions Required", + args: undefined, }, callsPermissionsRequiredDescription: { - en: 'You can enable the "Voice and Video Calls" permission in Privacy Settings.', - args: undefined, + en: "You can enable the \"Voice and Video Calls\" permission in Privacy Settings.", + args: undefined, }, callsPermissionsRequiredDescription1: { - en: 'You can enable the "Voice and Video Calls" permission in Permissions Settings.', - args: undefined, + en: "You can enable the \"Voice and Video Calls\" permission in Permissions Settings.", + args: undefined, }, callsReconnecting: { - en: 'Reconnecting…', - args: undefined, + en: "Reconnecting…", + args: undefined, }, callsRinging: { - en: 'Ringing...', - args: undefined, + en: "Ringing...", + args: undefined, }, callsSessionCall: { - en: 'Session Call', - args: undefined, + en: "Session Call", + args: undefined, }, callsSettings: { - en: 'Calls (Beta)', - args: undefined, + en: "Calls (Beta)", + args: undefined, }, callsVoiceAndVideo: { - en: 'Voice and Video Calls', - args: undefined, + en: "Voice and Video Calls", + args: undefined, }, callsVoiceAndVideoBeta: { - en: 'Voice and Video Calls (Beta)', - args: undefined, + en: "Voice and Video Calls (Beta)", + args: undefined, }, callsVoiceAndVideoModalDescription: { - en: 'Your IP is visible to your call partner and a Session Technology Foundation server while using beta calls.', - args: undefined, + en: "Your IP is visible to your call partner and a Session Technology Foundation server while using beta calls.", + args: undefined, }, callsVoiceAndVideoToggleDescription: { - en: 'Enables voice and video calls to and from other users.', - args: undefined, + en: "Enables voice and video calls to and from other users.", + args: undefined, }, callsYouCalled: { - en: 'You called {name}', - args: { name: 'string' }, + en: "You called {name}", + args: {name: "string"} }, callsYouMissedCallPermissions: { - en: "You missed a call from {name} because you haven't enabled Voice and Video Calls in Privacy Settings.", - args: { name: 'string' }, + en: "You missed a call from {name} because you haven't enabled Voice and Video Calls in Privacy Settings.", + args: {name: "string"} }, cameraErrorNotFound: { - en: 'No camera found', - args: undefined, + en: "No camera found", + args: undefined, }, cameraErrorUnavailable: { - en: 'Camera unavailable.', - args: undefined, + en: "Camera unavailable.", + args: undefined, }, cameraGrantAccess: { - en: 'Grant Camera Access', - args: undefined, + en: "Grant Camera Access", + args: undefined, }, cameraGrantAccessDenied: { - en: 'Session needs camera access to take photos and videos, but it has been permanently denied. Please continue to app settings, select "Permissions", and enable "Camera".', - args: undefined, + en: "Session needs camera access to take photos and videos, but it has been permanently denied. Please continue to app settings, select \"Permissions\", and enable \"Camera\".", + args: undefined, }, cameraGrantAccessDescription: { - en: 'Session needs camera access to take photos and videos, or scan QR codes.', - args: undefined, + en: "Session needs camera access to take photos and videos, or scan QR codes.", + args: undefined, }, cameraGrantAccessQr: { - en: 'Session needs camera access to scan QR codes', - args: undefined, + en: "Session needs camera access to scan QR codes", + args: undefined, }, cancel: { - en: 'Cancel', - args: undefined, + en: "Cancel", + args: undefined, }, changePasswordFail: { - en: 'Failed to change password', - args: undefined, + en: "Failed to change password", + args: undefined, }, clear: { - en: 'Clear', - args: undefined, + en: "Clear", + args: undefined, }, clearAll: { - en: 'Clear All', - args: undefined, + en: "Clear All", + args: undefined, }, clearDataAll: { - en: 'Clear All Data', - args: undefined, + en: "Clear All Data", + args: undefined, }, clearDataAllDescription: { - en: 'This will permanently delete your messages and contacts. Would you like to clear this device only, or delete your data from the network as well?', - args: undefined, + en: "This will permanently delete your messages and contacts. Would you like to clear this device only, or delete your data from the network as well?", + args: undefined, }, clearDataError: { - en: 'Data Not Deleted', - args: undefined, + en: "Data Not Deleted", + args: undefined, }, clearDataErrorDescriptionGeneric: { - en: 'An unknown error occurred and your data was not deleted. Do you want to delete your data from just this device instead?', - args: undefined, + en: "An unknown error occurred and your data was not deleted. Do you want to delete your data from just this device instead?", + args: undefined, }, clearDevice: { - en: 'Clear Device', - args: undefined, + en: "Clear Device", + args: undefined, }, clearDeviceAndNetwork: { - en: 'Clear device and network', - args: undefined, + en: "Clear device and network", + args: undefined, }, clearDeviceAndNetworkConfirm: { - en: 'Are you sure you want to delete your data from the network? If you continue, you will not be able to restore your messages or contacts.', - args: undefined, + en: "Are you sure you want to delete your data from the network? If you continue, you will not be able to restore your messages or contacts.", + args: undefined, }, clearDeviceDescription: { - en: 'Are you sure you want to clear your device?', - args: undefined, + en: "Are you sure you want to clear your device?", + args: undefined, }, clearDeviceOnly: { - en: 'Clear device only', - args: undefined, + en: "Clear device only", + args: undefined, + }, + clearDeviceRestart: { + en: "Clear Device and Restart", + args: undefined, + }, + clearDeviceRestore: { + en: "Clear Device and Restore", + args: undefined, }, clearMessages: { - en: 'Clear All Messages', - args: undefined, + en: "Clear All Messages", + args: undefined, }, clearMessagesChatDescription: { - en: 'Are you sure you want to clear all messages from your conversation with {name} from your device?', - args: { name: 'string' }, + en: "Are you sure you want to clear all messages from your conversation with {name} from your device?", + args: {name: "string"} + }, + clearMessagesChatDescriptionUpdated: { + en: "Are you sure you want to clear all messages from your conversation with {name} on this device?", + args: {name: "string"} }, clearMessagesCommunity: { - en: 'Are you sure you want to clear all {community_name} messages from your device?', - args: { community_name: 'string' }, + en: "Are you sure you want to clear all {community_name} messages from your device?", + args: {community_name: "string"} + }, + clearMessagesCommunityUpdated: { + en: "Are you sure you want to clear all messages from {community_name} on this device?", + args: {community_name: "string"} }, clearMessagesForEveryone: { - en: 'Clear for everyone', - args: undefined, + en: "Clear for everyone", + args: undefined, }, clearMessagesForMe: { - en: 'Clear for me', - args: undefined, + en: "Clear for me", + args: undefined, }, clearMessagesGroupAdminDescription: { - en: 'Are you sure you want to clear all {group_name} messages?', - args: { group_name: 'string' }, + en: "Are you sure you want to clear all {group_name} messages?", + args: {group_name: "string"} + }, + clearMessagesGroupAdminDescriptionUpdated: { + en: "Are you sure you want to clear all messages from {group_name}?", + args: {group_name: "string"} }, clearMessagesGroupDescription: { - en: 'Are you sure you want to clear all {group_name} messages from your device?', - args: { group_name: 'string' }, + en: "Are you sure you want to clear all {group_name} messages from your device?", + args: {group_name: "string"} + }, + clearMessagesGroupDescriptionUpdated: { + en: "Are you sure you want to clear all messages from {group_name} on this device?", + args: {group_name: "string"} }, clearMessagesNoteToSelfDescription: { - en: 'Are you sure you want to clear all Note to Self messages from your device?', - args: undefined, + en: "Are you sure you want to clear all Note to Self messages from your device?", + args: undefined, + }, + clearMessagesNoteToSelfDescriptionUpdated: { + en: "Are you sure you want to clear all Note to Self messages on this device?", + args: undefined, + }, + clearOnThisDevice: { + en: "Clear on this device", + args: undefined, }, close: { - en: 'Close', - args: undefined, + en: "Close", + args: undefined, + }, + closeApp: { + en: "Close App", + args: undefined, }, closeWindow: { - en: 'Close Window', - args: undefined, + en: "Close Window", + args: undefined, }, commitHashDesktop: { - en: 'Commit Hash: {hash}', - args: { hash: 'string' }, + en: "Commit Hash: {hash}", + args: {hash: "string"} }, communityBanDeleteDescription: { - en: 'This will ban the selected user from this Community and delete all their messages. Are you sure you want to continue?', - args: undefined, + en: "This will ban the selected user from this Community and delete all their messages. Are you sure you want to continue?", + args: undefined, }, communityBanDescription: { - en: 'This will ban the selected user from this Community. Are you sure you want to continue?', - args: undefined, + en: "This will ban the selected user from this Community. Are you sure you want to continue?", + args: undefined, }, communityEnterUrl: { - en: 'Enter Community URL', - args: undefined, + en: "Enter Community URL", + args: undefined, }, communityEnterUrlErrorInvalid: { - en: 'Invalid URL', - args: undefined, + en: "Invalid URL", + args: undefined, }, communityEnterUrlErrorInvalidDescription: { - en: 'Please check the Community URL and try again.', - args: undefined, + en: "Please check the Community URL and try again.", + args: undefined, }, communityError: { - en: 'Community Error', - args: undefined, + en: "Community Error", + args: undefined, }, communityErrorDescription: { - en: 'Oops, an error occurred. Please try again later.', - args: undefined, + en: "Oops, an error occurred. Please try again later.", + args: undefined, }, communityInvitation: { - en: 'Community Invitation', - args: undefined, + en: "Community Invitation", + args: undefined, }, communityJoin: { - en: 'Join Community', - args: undefined, + en: "Join Community", + args: undefined, }, communityJoinDescription: { - en: 'Are you sure you want to join {community_name}?', - args: { community_name: 'string' }, + en: "Are you sure you want to join {community_name}?", + args: {community_name: "string"} }, communityJoinError: { - en: 'Failed to join community', - args: undefined, + en: "Failed to join community", + args: undefined, }, communityJoinOfficial: { - en: 'Or join one of these...', - args: undefined, + en: "Or join one of these...", + args: undefined, }, communityJoined: { - en: 'Joined Community', - args: undefined, + en: "Joined Community", + args: undefined, }, communityJoinedAlready: { - en: 'You are already a member of this community.', - args: undefined, + en: "You are already a member of this community.", + args: undefined, }, communityLeave: { - en: 'Leave Community', - args: undefined, + en: "Leave Community", + args: undefined, }, communityLeaveError: { - en: 'Failed to leave {community_name}', - args: { community_name: 'string' }, + en: "Failed to leave {community_name}", + args: {community_name: "string"} }, communityUnknown: { - en: 'Unknown Community', - args: undefined, + en: "Unknown Community", + args: undefined, }, communityUrl: { - en: 'Community URL', - args: undefined, + en: "Community URL", + args: undefined, }, communityUrlCopy: { - en: 'Copy Community URL', - args: undefined, + en: "Copy Community URL", + args: undefined, }, confirm: { - en: 'Confirm', - args: undefined, + en: "Confirm", + args: undefined, }, contactContacts: { - en: 'Contacts', - args: undefined, + en: "Contacts", + args: undefined, }, contactDelete: { - en: 'Delete Contact', - args: undefined, + en: "Delete Contact", + args: undefined, }, contactDeleteDescription: { - en: 'Are you sure you want to delete {name} from your contacts? New messages from {name} will arrive as a message request.', - args: { name: 'string' }, + en: "Are you sure you want to delete {name} from your contacts? New messages from {name} will arrive as a message request.", + args: {name: "string"} }, contactNone: { - en: "You don't have any contacts yet", - args: undefined, + en: "You don't have any contacts yet", + args: undefined, }, contactSelect: { - en: 'Select Contacts', - args: undefined, + en: "Select Contacts", + args: undefined, }, contactUserDetails: { - en: 'User Details', - args: undefined, + en: "User Details", + args: undefined, }, contentDescriptionCamera: { - en: 'Camera', - args: undefined, + en: "Camera", + args: undefined, }, contentDescriptionChooseConversationType: { - en: 'Choose an action to start a conversation', - args: undefined, + en: "Choose an action to start a conversation", + args: undefined, }, contentDescriptionMediaMessage: { - en: 'Media message', - args: undefined, + en: "Media message", + args: undefined, }, contentDescriptionMessageComposition: { - en: 'Message composition', - args: undefined, + en: "Message composition", + args: undefined, }, contentDescriptionQuoteThumbnail: { - en: 'Thumbnail of image from quoted message', - args: undefined, + en: "Thumbnail of image from quoted message", + args: undefined, }, contentDescriptionStartConversation: { - en: 'Create a conversation with a new contact', - args: undefined, + en: "Create a conversation with a new contact", + args: undefined, }, conversationsAddToHome: { - en: 'Add to home screen', - args: undefined, + en: "Add to home screen", + args: undefined, }, conversationsAddedToHome: { - en: 'Added to home screen', - args: undefined, + en: "Added to home screen", + args: undefined, }, conversationsAudioMessages: { - en: 'Audio Messages', - args: undefined, + en: "Audio Messages", + args: undefined, }, conversationsAutoplayAudioMessage: { - en: 'Autoplay Audio Messages', - args: undefined, + en: "Autoplay Audio Messages", + args: undefined, }, conversationsAutoplayAudioMessageDescription: { - en: 'Autoplay consecutively sent audio messages.', - args: undefined, + en: "Autoplay consecutively sent audio messages.", + args: undefined, }, conversationsBlockedContacts: { - en: 'Blocked Contacts', - args: undefined, + en: "Blocked Contacts", + args: undefined, }, conversationsCommunities: { - en: 'Communities', - args: undefined, + en: "Communities", + args: undefined, }, conversationsDelete: { - en: 'Delete Conversation', - args: undefined, + en: "Delete Conversation", + args: undefined, }, conversationsDeleteDescription: { - en: 'Are you sure you want to delete your conversation with {name}? New messages from {name} will start a new conversation.', - args: { name: 'string' }, + en: "Are you sure you want to delete your conversation with {name}? New messages from {name} will start a new conversation.", + args: {name: "string"} }, conversationsDeleted: { - en: 'Conversation deleted', - args: undefined, + en: "Conversation deleted", + args: undefined, }, conversationsEmpty: { - en: 'There are no messages in {conversation_name}.', - args: { conversation_name: 'string' }, + en: "There are no messages in {conversation_name}.", + args: {conversation_name: "string"} }, conversationsEnter: { - en: 'Enter Key', - args: undefined, + en: "Enter Key", + args: undefined, }, conversationsEnterDescription: { - en: 'Function of the enter key when typing in a conversation.', - args: undefined, + en: "Function of the enter key when typing in a conversation.", + args: undefined, }, conversationsEnterNewLine: { - en: 'SHIFT + ENTER sends a message, ENTER starts a new line', - args: undefined, + en: "SHIFT + ENTER sends a message, ENTER starts a new line", + args: undefined, }, conversationsEnterSends: { - en: 'ENTER sends a message, SHIFT + ENTER starts a new line', - args: undefined, + en: "ENTER sends a message, SHIFT + ENTER starts a new line", + args: undefined, }, conversationsGroups: { - en: 'Groups', - args: undefined, + en: "Groups", + args: undefined, }, conversationsMessageTrimming: { - en: 'Message Trimming', - args: undefined, + en: "Message Trimming", + args: undefined, }, conversationsMessageTrimmingTrimCommunities: { - en: 'Trim Communities', - args: undefined, + en: "Trim Communities", + args: undefined, }, conversationsMessageTrimmingTrimCommunitiesDescription: { - en: 'Delete messages from Community conversations older than 6 months, and where there are over 2,000 messages.', - args: undefined, + en: "Delete messages from Community conversations older than 6 months, and where there are over 2,000 messages.", + args: undefined, }, conversationsNew: { - en: 'New Conversation', - args: undefined, + en: "New Conversation", + args: undefined, }, conversationsNone: { - en: "You don't have any conversations yet", - args: undefined, + en: "You don't have any conversations yet", + args: undefined, }, conversationsSendWithEnterKey: { - en: 'Send with Enter Key', - args: undefined, + en: "Send with Enter Key", + args: undefined, }, conversationsSendWithEnterKeyDescription: { - en: 'Tapping the Enter Key will send message instead of starting a new line.', - args: undefined, + en: "Tapping the Enter Key will send message instead of starting a new line.", + args: undefined, }, conversationsSettingsAllMedia: { - en: 'All Media', - args: undefined, + en: "All Media", + args: undefined, }, conversationsSpellCheck: { - en: 'Spell Check', - args: undefined, + en: "Spell Check", + args: undefined, }, conversationsSpellCheckDescription: { - en: 'Enable spell check when typing messages.', - args: undefined, + en: "Enable spell check when typing messages.", + args: undefined, }, conversationsStart: { - en: 'Start Conversation', - args: undefined, + en: "Start Conversation", + args: undefined, }, copied: { - en: 'Copied', - args: undefined, + en: "Copied", + args: undefined, }, copy: { - en: 'Copy', - args: undefined, + en: "Copy", + args: undefined, }, create: { - en: 'Create', - args: undefined, + en: "Create", + args: undefined, }, creatingCall: { - en: 'Creating Call', - args: undefined, + en: "Creating Call", + args: undefined, }, cut: { - en: 'Cut', - args: undefined, + en: "Cut", + args: undefined, + }, + databaseErrorClearDataWarning: { + en: "Are you sure you want to delete all messages, attachments, and account data from this device and create a new account?", + args: undefined, }, databaseErrorGeneric: { - en: 'A database error occurred.

Export your application logs to share for troubleshooting. If this is unsuccessful, reinstall Session and restore your account.

Warning: This will result in loss of all messages, attachments, and account data older than two weeks.', - args: undefined, + en: "A database error occurred.

Export your application logs to share for troubleshooting. If this is unsuccessful, reinstall Session and restore your account.", + args: undefined, + }, + databaseErrorRestoreDataWarning: { + en: "Are you sure you want to delete all messages, attachments, and account data from this device and restore your account from the network?", + args: undefined, }, databaseErrorTimeout: { - en: "We've noticed Session is taking a long time to start.

You can continue to wait, export your device logs to share for troubleshooting, or try restarting Session.", - args: undefined, + en: "We've noticed Session is taking a long time to start.

You can continue to wait, export your device logs to share for troubleshooting, or try restarting Session.", + args: undefined, }, databaseErrorUpdate: { - en: 'Your app database is incompatible with this version of Session. Reinstall the app and restore your account to generate a new database and continue using Session.

Warning: This will result in the loss of all messages and attachments older than two weeks.', - args: undefined, + en: "Your app database is incompatible with this version of Session. Reinstall the app and restore your account to generate a new database and continue using Session.

Warning: This will result in the loss of all messages and attachments older than two weeks.", + args: undefined, }, databaseOptimizing: { - en: 'Optimizing Database', - args: undefined, + en: "Optimizing Database", + args: undefined, }, debugLog: { - en: 'Debug Log', - args: undefined, + en: "Debug Log", + args: undefined, }, decline: { - en: 'Decline', - args: undefined, + en: "Decline", + args: undefined, }, delete: { - en: 'Delete', - args: undefined, + en: "Delete", + args: undefined, }, deleteAfterGroupFirstReleaseConfigOutdated: { - en: 'Some of your devices are using outdated versions. Syncing may be unreliable until they are updated.', - args: undefined, + en: "Some of your devices are using outdated versions. Syncing may be unreliable until they are updated.", + args: undefined, }, deleteAfterGroupPR1BlockThisUser: { - en: 'Block This User', - args: undefined, + en: "Block This User", + args: undefined, }, deleteAfterGroupPR1BlockUser: { - en: 'Block User', - args: undefined, + en: "Block User", + args: undefined, }, deleteAfterGroupPR1GroupSettings: { - en: 'Group Settings', - args: undefined, + en: "Group Settings", + args: undefined, }, deleteAfterGroupPR1MentionsOnly: { - en: 'Notify for Mentions Only', - args: undefined, + en: "Notify for Mentions Only", + args: undefined, }, deleteAfterGroupPR1MentionsOnlyDescription: { - en: "When enabled, you'll only be notified for messages mentioning you.", - args: undefined, + en: "When enabled, you'll only be notified for messages mentioning you.", + args: undefined, }, deleteAfterGroupPR1MessageSound: { - en: 'Message Sound', - args: undefined, + en: "Message Sound", + args: undefined, }, deleteAfterGroupPR3DeleteMessagesConfirmation: { - en: 'Permanently delete the messages in this conversation?', - args: undefined, + en: "Permanently delete the messages in this conversation?", + args: undefined, }, deleteAfterGroupPR3GroupErrorLeave: { - en: "Can't leave while adding or removing other members.", - args: undefined, + en: "Can't leave while adding or removing other members.", + args: undefined, }, deleteAfterLegacyDisappearingMessagesLegacy: { - en: 'Legacy', - args: undefined, + en: "Legacy", + args: undefined, }, deleteAfterLegacyDisappearingMessagesOriginal: { - en: 'Original version of disappearing messages.', - args: undefined, + en: "Original version of disappearing messages.", + args: undefined, }, deleteAfterLegacyDisappearingMessagesTheyChangedTimer: { - en: '{name} set the disappearing message timer to {time}', - args: { name: 'string', time: 'string' }, + en: "{name} set the disappearing message timer to {time}", + args: {name: "string", time: "string"} }, deleteAfterLegacyGroupsGroupCreation: { - en: 'Please wait while the group is created...', - args: undefined, + en: "Please wait while the group is created...", + args: undefined, }, deleteAfterLegacyGroupsGroupUpdateErrorTitle: { - en: 'Failed to Update Group', - args: undefined, + en: "Failed to Update Group", + args: undefined, }, deleteAfterMessageDeletionStandardisationMessageDeletionForbidden: { - en: 'You don’t have permission to delete others’ messages', - args: undefined, + en: "You don’t have permission to delete others’ messages", + args: undefined, + }, + deleteContactDescription: { + en: "Are you sure you want to delete {name} from your contacts?

This will delete your conversation, including all messages and attachments. Future messages from {name} will appear as a message request.", + args: {name: "string"} + }, + deleteConversationDescription: { + en: "Are you sure you want to delete your conversation with {name}?
This will permanently delete all messages and attachments.", + args: {name: "string"} }, deleteMessageDeletedGlobally: { - en: 'This message was deleted', - args: undefined, + en: "This message was deleted", + args: undefined, }, deleteMessageDeletedLocally: { - en: 'This message was deleted on this device', - args: undefined, + en: "This message was deleted on this device", + args: undefined, }, deleteMessageDescriptionEveryone: { - en: 'Are you sure you want to delete this message for everyone?', - args: undefined, + en: "Are you sure you want to delete this message for everyone?", + args: undefined, }, deleteMessageDeviceOnly: { - en: 'Delete on this device only', - args: undefined, + en: "Delete on this device only", + args: undefined, }, deleteMessageDevicesAll: { - en: 'Delete on all my devices', - args: undefined, + en: "Delete on all my devices", + args: undefined, }, deleteMessageEveryone: { - en: 'Delete for everyone', - args: undefined, + en: "Delete for everyone", + args: undefined, }, deleteMessagesDescriptionEveryone: { - en: 'Are you sure you want to delete these messages for everyone?', - args: undefined, + en: "Are you sure you want to delete these messages for everyone?", + args: undefined, }, deleting: { - en: 'Deleting', - args: undefined, + en: "Deleting", + args: undefined, }, developerToolsToggle: { - en: 'Toggle Developer Tools', - args: undefined, + en: "Toggle Developer Tools", + args: undefined, }, dictationStart: { - en: 'Start Dictation...', - args: undefined, + en: "Start Dictation...", + args: undefined, }, disappearingMessages: { - en: 'Disappearing Messages', - args: undefined, + en: "Disappearing Messages", + args: undefined, }, disappearingMessagesCountdownBig: { - en: 'Message will delete in {time_large}', - args: { time_large: 'string' }, + en: "Message will delete in {time_large}", + args: {time_large: "string"} }, disappearingMessagesCountdownBigMobile: { - en: 'Auto-deletes in {time_large}', - args: { time_large: 'string' }, + en: "Auto-deletes in {time_large}", + args: {time_large: "string"} }, disappearingMessagesCountdownBigSmall: { - en: 'Message will delete in {time_large} {time_small}', - args: { time_large: 'string', time_small: 'string' }, + en: "Message will delete in {time_large} {time_small}", + args: {time_large: "string", time_small: "string"} }, disappearingMessagesCountdownBigSmallMobile: { - en: 'Auto-deletes in {time_large} {time_small}', - args: { time_large: 'string', time_small: 'string' }, + en: "Auto-deletes in {time_large} {time_small}", + args: {time_large: "string", time_small: "string"} }, disappearingMessagesDeleteType: { - en: 'Delete Type', - args: undefined, + en: "Delete Type", + args: undefined, }, disappearingMessagesDescription: { - en: 'This setting applies to everyone in this conversation.', - args: undefined, + en: "This setting applies to everyone in this conversation.", + args: undefined, }, disappearingMessagesDescription1: { - en: 'This setting applies to messages you send in this conversation.', - args: undefined, + en: "This setting applies to messages you send in this conversation.", + args: undefined, }, disappearingMessagesDescriptionGroup: { - en: 'This setting applies to everyone in this conversation.
Only group admins can change this setting.', - args: undefined, + en: "This setting applies to everyone in this conversation.
Only group admins can change this setting.", + args: undefined, }, disappearingMessagesDisappear: { - en: 'Disappear After {disappearing_messages_type} - {time}', - args: { disappearing_messages_type: 'string', time: 'string' }, + en: "Disappear After {disappearing_messages_type} - {time}", + args: {disappearing_messages_type: "string", time: "string"} }, disappearingMessagesDisappearAfterRead: { - en: 'Disappear After Read', - args: undefined, + en: "Disappear After Read", + args: undefined, }, disappearingMessagesDisappearAfterReadDescription: { - en: 'Messages delete after they have been read.', - args: undefined, + en: "Messages delete after they have been read.", + args: undefined, }, disappearingMessagesDisappearAfterReadState: { - en: 'Disappear After Read - {time}', - args: { time: 'string' }, + en: "Disappear After Read - {time}", + args: {time: "string"} }, disappearingMessagesDisappearAfterSend: { - en: 'Disappear After Send', - args: undefined, + en: "Disappear After Send", + args: undefined, }, disappearingMessagesDisappearAfterSendDescription: { - en: 'Messages delete after they have been sent.', - args: undefined, + en: "Messages delete after they have been sent.", + args: undefined, }, disappearingMessagesDisappearAfterSendState: { - en: 'Disappear After Send - {time}', - args: { time: 'string' }, + en: "Disappear After Send - {time}", + args: {time: "string"} }, disappearingMessagesFollowSetting: { - en: 'Follow Setting', - args: undefined, + en: "Follow Setting", + args: undefined, }, disappearingMessagesFollowSettingOff: { - en: 'Messages you send will no longer disappear. Are you sure you want to turn off disappearing messages?', - args: undefined, + en: "Messages you send will no longer disappear. Are you sure you want to turn off disappearing messages?", + args: undefined, }, disappearingMessagesFollowSettingOn: { - en: 'Set your messages to disappear {time} after they have been {disappearing_messages_type}?', - args: { time: 'string', disappearing_messages_type: 'string' }, + en: "Set your messages to disappear {time} after they have been {disappearing_messages_type}?", + args: {time: "string", disappearing_messages_type: "string"} }, disappearingMessagesLegacy: { - en: '{name} is using an outdated client. Disappearing messages may not work as expected.', - args: { name: 'string' }, + en: "{name} is using an outdated client. Disappearing messages may not work as expected.", + args: {name: "string"} }, disappearingMessagesOnlyAdmins: { - en: 'Only group admins can change this setting.', - args: undefined, + en: "Only group admins can change this setting.", + args: undefined, }, disappearingMessagesSent: { - en: 'Sent', - args: undefined, + en: "Sent", + args: undefined, }, disappearingMessagesSet: { - en: '{name} has set messages to disappear {time} after they have been {disappearing_messages_type}.', - args: { name: 'string', time: 'string', disappearing_messages_type: 'string' }, + en: "{name} has set messages to disappear {time} after they have been {disappearing_messages_type}.", + args: {name: "string", time: "string", disappearing_messages_type: "string"} }, disappearingMessagesSetYou: { - en: 'You set messages to disappear {time} after they have been {disappearing_messages_type}.', - args: { time: 'string', disappearing_messages_type: 'string' }, + en: "You set messages to disappear {time} after they have been {disappearing_messages_type}.", + args: {time: "string", disappearing_messages_type: "string"} }, disappearingMessagesTimer: { - en: 'Timer', - args: undefined, + en: "Timer", + args: undefined, }, disappearingMessagesTurnedOff: { - en: '{name} has turned disappearing messages off. Messages they send will no longer disappear.', - args: { name: 'string' }, + en: "{name} has turned disappearing messages off. Messages they send will no longer disappear.", + args: {name: "string"} }, disappearingMessagesTurnedOffGroup: { - en: '{name} has turned disappearing messages off.', - args: { name: 'string' }, + en: "{name} has turned disappearing messages off.", + args: {name: "string"} }, disappearingMessagesTurnedOffYou: { - en: 'You turned off disappearing messages. Messages you send will no longer disappear.', - args: undefined, + en: "You turned off disappearing messages. Messages you send will no longer disappear.", + args: undefined, }, disappearingMessagesTurnedOffYouGroup: { - en: 'You turned off disappearing messages.', - args: undefined, + en: "You turned off disappearing messages.", + args: undefined, }, disappearingMessagesTypeRead: { - en: 'read', - args: undefined, + en: "read", + args: undefined, }, disappearingMessagesTypeSent: { - en: 'sent', - args: undefined, + en: "sent", + args: undefined, }, disappearingMessagesUpdated: { - en: '{admin_name} updated disappearing message settings.', - args: { admin_name: 'string' }, + en: "{admin_name} updated disappearing message settings.", + args: {admin_name: "string"} }, disappearingMessagesUpdatedYou: { - en: 'You updated disappearing message settings.', - args: undefined, + en: "You updated disappearing message settings.", + args: undefined, }, dismiss: { - en: 'Dismiss', - args: undefined, + en: "Dismiss", + args: undefined, }, displayNameDescription: { - en: 'It can be your real name, an alias, or anything else you like — and you can change it at any time.', - args: undefined, + en: "It can be your real name, an alias, or anything else you like — and you can change it at any time.", + args: undefined, }, displayNameEnter: { - en: 'Enter your display name', - args: undefined, + en: "Enter your display name", + args: undefined, }, displayNameErrorDescription: { - en: 'Please enter a display name', - args: undefined, + en: "Please enter a display name", + args: undefined, }, displayNameErrorDescriptionShorter: { - en: 'Please enter a shorter display name', - args: undefined, + en: "Please enter a shorter display name", + args: undefined, }, displayNameErrorNew: { - en: 'We were unable to load your display name. Please enter a new display name to continue.', - args: undefined, + en: "We were unable to load your display name. Please enter a new display name to continue.", + args: undefined, }, displayNameNew: { - en: 'Pick a new display name', - args: undefined, + en: "Pick a new display name", + args: undefined, }, displayNamePick: { - en: 'Pick your display name', - args: undefined, + en: "Pick your display name", + args: undefined, }, displayNameSet: { - en: 'Set Display Name', - args: undefined, + en: "Set Display Name", + args: undefined, }, displayNameVisible: { - en: 'Your Display Name is visible to users, groups and communities you interact with.', - args: undefined, + en: "Your Display Name is visible to users, groups and communities you interact with.", + args: undefined, }, document: { - en: 'Document', - args: undefined, + en: "Document", + args: undefined, + }, + donate: { + en: "Donate", + args: undefined, }, done: { - en: 'Done', - args: undefined, + en: "Done", + args: undefined, }, download: { - en: 'Download', - args: undefined, + en: "Download", + args: undefined, }, downloading: { - en: 'Downloading...', - args: undefined, + en: "Downloading...", + args: undefined, }, draft: { - en: 'Draft', - args: undefined, + en: "Draft", + args: undefined, }, edit: { - en: 'Edit', - args: undefined, + en: "Edit", + args: undefined, }, emojiAndSymbols: { - en: 'Emoji and Symbols', - args: undefined, + en: "Emoji and Symbols", + args: undefined, }, emojiCategoryActivities: { - en: 'Activities', - args: undefined, + en: "Activities", + args: undefined, }, emojiCategoryAnimals: { - en: 'Animals and Nature', - args: undefined, + en: "Animals and Nature", + args: undefined, }, emojiCategoryFlags: { - en: 'Flags', - args: undefined, + en: "Flags", + args: undefined, }, emojiCategoryFood: { - en: 'Food and Drink', - args: undefined, + en: "Food and Drink", + args: undefined, }, emojiCategoryObjects: { - en: 'Objects', - args: undefined, + en: "Objects", + args: undefined, }, emojiCategoryRecentlyUsed: { - en: 'Recently Used', - args: undefined, + en: "Recently Used", + args: undefined, }, emojiCategorySmileys: { - en: 'Smileys and People', - args: undefined, + en: "Smileys and People", + args: undefined, }, emojiCategorySymbols: { - en: 'Symbols', - args: undefined, + en: "Symbols", + args: undefined, }, emojiCategoryTravel: { - en: 'Travel and Places', - args: undefined, + en: "Travel and Places", + args: undefined, }, emojiReactsClearAll: { - en: 'Are you sure you want to clear all {emoji}?', - args: { emoji: 'string' }, + en: "Are you sure you want to clear all {emoji}?", + args: {emoji: "string"} }, emojiReactsCoolDown: { - en: "Slow down! You've sent too many emoji reacts. Try again soon", - args: undefined, + en: "Slow down! You've sent too many emoji reacts. Try again soon", + args: undefined, }, emojiReactsHoverNameDesktop: { - en: '{name} reacted with {emoji_name}', - args: { name: 'string', emoji_name: 'string' }, + en: "{name} reacted with {emoji_name}", + args: {name: "string", emoji_name: "string"} }, emojiReactsHoverNameTwoDesktop: { - en: '{name} and {other_name} reacted with {emoji_name}', - args: { name: 'string', other_name: 'string', emoji_name: 'string' }, + en: "{name} and {other_name} reacted with {emoji_name}", + args: {name: "string", other_name: "string", emoji_name: "string"} }, emojiReactsHoverTwoNameMultipleDesktop: { - en: '{name} and {count} others reacted with {emoji_name}', - args: { name: 'string', count: 'number', emoji_name: 'string' }, + en: "{name} and {count} others reacted with {emoji_name}", + args: {name: "string", count: "number", emoji_name: "string"} }, emojiReactsHoverYouNameDesktop: { - en: 'You reacted with {emoji_name}', - args: { emoji_name: 'string' }, + en: "You reacted with {emoji_name}", + args: {emoji_name: "string"} }, emojiReactsHoverYouNameMultipleDesktop: { - en: 'You and {count} others reacted with {emoji_name}', - args: { count: 'number', emoji_name: 'string' }, + en: "You and {count} others reacted with {emoji_name}", + args: {count: "number", emoji_name: "string"} }, emojiReactsHoverYouNameTwoDesktop: { - en: 'You and {name} reacted with {emoji_name}', - args: { name: 'string', emoji_name: 'string' }, + en: "You and {name} reacted with {emoji_name}", + args: {name: "string", emoji_name: "string"} }, emojiReactsNotification: { - en: 'Reacted to your message {emoji}', - args: { emoji: 'string' }, + en: "Reacted to your message {emoji}", + args: {emoji: "string"} }, enable: { - en: 'Enable', - args: undefined, + en: "Enable", + args: undefined, }, errorConnection: { - en: 'Please check your internet connection and try again.', - args: undefined, + en: "Please check your internet connection and try again.", + args: undefined, }, errorCopyAndQuit: { - en: 'Copy Error and Quit', - args: undefined, + en: "Copy Error and Quit", + args: undefined, }, errorDatabase: { - en: 'Database Error', - args: undefined, + en: "Database Error", + args: undefined, + }, + errorGeneric: { + en: "Something went wrong. Please try again later.", + args: undefined, }, errorUnknown: { - en: 'An unknown error occurred.', - args: undefined, + en: "An unknown error occurred.", + args: undefined, }, failedToDownload: { - en: 'Failed to download', - args: undefined, + en: "Failed to download", + args: undefined, }, failures: { - en: 'Failures', - args: undefined, + en: "Failures", + args: undefined, }, file: { - en: 'File', - args: undefined, + en: "File", + args: undefined, }, files: { - en: 'Files', - args: undefined, + en: "Files", + args: undefined, }, followSystemSettings: { - en: 'Follow system settings', - args: undefined, + en: "Follow system settings", + args: undefined, + }, + forever: { + en: "Forever", + args: undefined, }, from: { - en: 'From:', - args: undefined, + en: "From:", + args: undefined, }, fullScreenToggle: { - en: 'Toggle Full Screen', - args: undefined, + en: "Toggle Full Screen", + args: undefined, }, gif: { - en: 'GIF', - args: undefined, + en: "GIF", + args: undefined, }, giphyWarning: { - en: 'Giphy', - args: undefined, + en: "Giphy", + args: undefined, }, giphyWarningDescription: { - en: 'Session will connect to Giphy to provide search results. You will not have full metadata protection when sending GIFs.', - args: undefined, + en: "Session will connect to Giphy to provide search results. You will not have full metadata protection when sending GIFs.", + args: undefined, }, groupAddMemberMaximum: { - en: 'Groups have a maximum of 100 members', - args: undefined, + en: "Groups have a maximum of 100 members", + args: undefined, }, groupCreate: { - en: 'Create Group', - args: undefined, + en: "Create Group", + args: undefined, }, groupCreateErrorNoMembers: { - en: 'Please pick at least one other group member.', - args: undefined, + en: "Please pick at least one other group member.", + args: undefined, }, groupDelete: { - en: 'Delete Group', - args: undefined, + en: "Delete Group", + args: undefined, }, groupDeleteDescription: { - en: 'Are you sure you want to delete {group_name}? This will remove all members and delete all group content.', - args: { group_name: 'string' }, + en: "Are you sure you want to delete {group_name}?

This will remove all members and delete all group content.", + args: {group_name: "string"} }, groupDeleteDescriptionMember: { - en: 'Are you sure you want to delete {group_name}?', - args: { group_name: 'string' }, + en: "Are you sure you want to delete {group_name}?", + args: {group_name: "string"} }, groupDeletedMemberDescription: { - en: '{group_name} has been deleted by a group admin. You will not be able to send any more messages.', - args: { group_name: 'string' }, + en: "{group_name} has been deleted by a group admin. You will not be able to send any more messages.", + args: {group_name: "string"} }, groupDescriptionEnter: { - en: 'Enter a group description', - args: undefined, + en: "Enter a group description", + args: undefined, }, groupDisplayPictureUpdated: { - en: 'Group display picture updated.', - args: undefined, + en: "Group display picture updated.", + args: undefined, }, groupEdit: { - en: 'Edit Group', - args: undefined, + en: "Edit Group", + args: undefined, }, groupError: { - en: 'Group Error', - args: undefined, + en: "Group Error", + args: undefined, }, groupErrorCreate: { - en: 'Failed to create group. Please check your internet connection and try again.', - args: undefined, + en: "Failed to create group. Please check your internet connection and try again.", + args: undefined, }, groupErrorJoin: { - en: 'Failed to join {group_name}', - args: { group_name: 'string' }, + en: "Failed to join {group_name}", + args: {group_name: "string"} }, groupInformationSet: { - en: 'Set Group Information', - args: undefined, + en: "Set Group Information", + args: undefined, }, groupInviteDelete: { - en: 'Are you sure you want to delete this group invite?', - args: undefined, + en: "Are you sure you want to delete this group invite?", + args: undefined, }, groupInviteFailed: { - en: 'Invite failed', - args: undefined, + en: "Invite failed", + args: undefined, }, groupInviteFailedMultiple: { - en: 'Failed to invite {name} and {count} others to {group_name}', - args: { name: 'string', count: 'number', group_name: 'string' }, + en: "Failed to invite {name} and {count} others to {group_name}", + args: {name: "string", count: "number", group_name: "string"} }, groupInviteFailedTwo: { - en: 'Failed to invite {name} and {other_name} to {group_name}', - args: { name: 'string', other_name: 'string', group_name: 'string' }, + en: "Failed to invite {name} and {other_name} to {group_name}", + args: {name: "string", other_name: "string", group_name: "string"} }, groupInviteFailedUser: { - en: 'Failed to invite {name} to {group_name}', - args: { name: 'string', group_name: 'string' }, + en: "Failed to invite {name} to {group_name}", + args: {name: "string", group_name: "string"} }, groupInviteNotSent: { - en: 'Invite not sent', - args: undefined, + en: "Invite not sent", + args: undefined, }, groupInviteReinvite: { - en: '{name} invited you to rejoin {group_name}, where you are an Admin.', - args: { name: 'string', group_name: 'string' }, + en: "{name} invited you to rejoin {group_name}, where you are an Admin.", + args: {name: "string", group_name: "string"} }, groupInviteReinviteYou: { - en: 'You were invited to rejoin {group_name}, where you are an Admin.', - args: { group_name: 'string' }, + en: "You were invited to rejoin {group_name}, where you are an Admin.", + args: {group_name: "string"} }, groupInviteSent: { - en: 'Invite sent', - args: undefined, + en: "Invite sent", + args: undefined, }, groupInviteStatusUnknown: { - en: 'Invite status unknown', - args: undefined, + en: "Invite status unknown", + args: undefined, }, groupInviteSuccessful: { - en: 'Group invite successful', - args: undefined, + en: "Group invite successful", + args: undefined, }, groupInviteVersion: { - en: 'Users must have the latest release to receive invitations', - args: undefined, + en: "Users must have the latest release to receive invitations", + args: undefined, }, groupInviteYou: { - en: 'You were invited to join the group.', - args: undefined, + en: "You were invited to join the group.", + args: undefined, }, groupInviteYouAndMoreNew: { - en: 'You and {count} others were invited to join the group.', - args: { count: 'number' }, + en: "You and {count} others were invited to join the group.", + args: {count: "number"} }, groupInviteYouAndOtherNew: { - en: 'You and {other_name} were invited to join the group.', - args: { other_name: 'string' }, + en: "You and {other_name} were invited to join the group.", + args: {other_name: "string"} }, groupInviteYouHistory: { - en: 'You were invited to join the group. Chat history was shared.', - args: undefined, + en: "You were invited to join the group. Chat history was shared.", + args: undefined, }, groupLeave: { - en: 'Leave Group', - args: undefined, + en: "Leave Group", + args: undefined, }, groupLeaveDescription: { - en: 'Are you sure you want to leave {group_name}?', - args: { group_name: 'string' }, + en: "Are you sure you want to leave {group_name}?", + args: {group_name: "string"} }, groupLeaveDescriptionAdmin: { - en: 'Are you sure you want to leave {group_name}?

This will remove all members and delete all group content.', - args: { group_name: 'string' }, + en: "Are you sure you want to leave {group_name}?

This will remove all members and delete all group content.", + args: {group_name: "string"} }, groupLeaveErrorFailed: { - en: 'Failed to leave {group_name}', - args: { group_name: 'string' }, + en: "Failed to leave {group_name}", + args: {group_name: "string"} }, groupMemberLeft: { - en: '{name} left the group.', - args: { name: 'string' }, + en: "{name} left the group.", + args: {name: "string"} }, groupMemberLeftMultiple: { - en: '{name} and {count} others left the group.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others left the group.", + args: {name: "string", count: "number"} }, groupMemberLeftTwo: { - en: '{name} and {other_name} left the group.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} left the group.", + args: {name: "string", other_name: "string"} }, groupMemberNew: { - en: '{name} was invited to join the group.', - args: { name: 'string' }, + en: "{name} was invited to join the group.", + args: {name: "string"} }, groupMemberNewHistory: { - en: '{name} was invited to join the group. Chat history was shared.', - args: { name: 'string' }, + en: "{name} was invited to join the group. Chat history was shared.", + args: {name: "string"} }, groupMemberNewHistoryMultiple: { - en: '{name} and {count} others were invited to join the group. Chat history was shared.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others were invited to join the group. Chat history was shared.", + args: {name: "string", count: "number"} }, groupMemberNewHistoryTwo: { - en: '{name} and {other_name} were invited to join the group. Chat history was shared.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} were invited to join the group. Chat history was shared.", + args: {name: "string", other_name: "string"} }, groupMemberNewMultiple: { - en: '{name} and {count} others were invited to join the group.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others were invited to join the group.", + args: {name: "string", count: "number"} }, groupMemberNewTwo: { - en: '{name} and {other_name} were invited to join the group.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} were invited to join the group.", + args: {name: "string", other_name: "string"} }, groupMemberNewYouHistoryMultiple: { - en: 'You and {count} others were invited to join the group. Chat history was shared.', - args: { count: 'number' }, + en: "You and {count} others were invited to join the group. Chat history was shared.", + args: {count: "number"} }, groupMemberNewYouHistoryTwo: { - en: 'You and {other_name} were invited to join the group. Chat history was shared.', - args: { other_name: 'string' }, + en: "You and {other_name} were invited to join the group. Chat history was shared.", + args: {other_name: "string"} }, groupMemberYouLeft: { - en: 'You left the group.', - args: undefined, + en: "You left the group.", + args: undefined, }, groupMembers: { - en: 'Group Members', - args: undefined, + en: "Group Members", + args: undefined, }, groupMembersNone: { - en: 'There are no other members in this group.', - args: undefined, + en: "There are no other members in this group.", + args: undefined, }, groupName: { - en: 'Group Name', - args: undefined, + en: "Group Name", + args: undefined, }, groupNameEnter: { - en: 'Enter a group name', - args: undefined, + en: "Enter a group name", + args: undefined, }, groupNameEnterPlease: { - en: 'Please enter a group name.', - args: undefined, + en: "Please enter a group name.", + args: undefined, }, groupNameEnterShorter: { - en: 'Please enter a shorter group name.', - args: undefined, + en: "Please enter a shorter group name", + args: undefined, }, groupNameNew: { - en: 'Group name is now {group_name}.', - args: { group_name: 'string' }, + en: "Group name is now {group_name}.", + args: {group_name: "string"} }, groupNameUpdated: { - en: 'Group name updated.', - args: undefined, + en: "Group name updated.", + args: undefined, }, groupNameVisible: { - en: 'Group name is visible to all group members.', - args: undefined, + en: "Group name is visible to all group members.", + args: undefined, }, groupNoMessages: { - en: 'You have no messages from {group_name}. Send a message to start the conversation!', - args: { group_name: 'string' }, + en: "You have no messages from {group_name}. Send a message to start the conversation!", + args: {group_name: "string"} }, groupNotUpdatedWarning: { - en: 'Group has not been updated in over 30 days. You may experience issues sending messages or viewing Group information.', - args: undefined, + en: "This group has not been updated in over 30 days. You may experience issues sending messages or viewing group information.", + args: undefined, }, groupOnlyAdmin: { - en: 'You are the only admin in {group_name}.

Group members and settings cannot be changed without an admin.', - args: { group_name: 'string' }, + en: "You are the only admin in {group_name}.

Group members and settings cannot be changed without an admin.", + args: {group_name: "string"} }, groupPendingRemoval: { - en: 'Pending removal', - args: undefined, + en: "Pending removal", + args: undefined, }, groupPromotedYou: { - en: 'You were promoted to Admin.', - args: undefined, + en: "You were promoted to Admin.", + args: undefined, }, groupPromotedYouMultiple: { - en: 'You and {count} others were promoted to Admin.', - args: { count: 'number' }, + en: "You and {count} others were promoted to Admin.", + args: {count: "number"} }, groupPromotedYouTwo: { - en: 'You and {other_name} were promoted to Admin.', - args: { other_name: 'string' }, + en: "You and {other_name} were promoted to Admin.", + args: {other_name: "string"} }, groupRemoveDescription: { - en: 'Would you like to remove {name} from {group_name}?', - args: { name: 'string', group_name: 'string' }, + en: "Would you like to remove {name} from {group_name}?", + args: {name: "string", group_name: "string"} }, groupRemoveDescriptionMultiple: { - en: 'Would you like to remove {name} and {count} others from {group_name}?', - args: { name: 'string', count: 'number', group_name: 'string' }, + en: "Would you like to remove {name} and {count} others from {group_name}?", + args: {name: "string", count: "number", group_name: "string"} }, groupRemoveDescriptionTwo: { - en: 'Would you like to remove {name} and {other_name} from {group_name}?', - args: { name: 'string', other_name: 'string', group_name: 'string' }, + en: "Would you like to remove {name} and {other_name} from {group_name}?", + args: {name: "string", other_name: "string", group_name: "string"} }, groupRemoved: { - en: '{name} was removed from the group.', - args: { name: 'string' }, + en: "{name} was removed from the group.", + args: {name: "string"} }, groupRemovedMultiple: { - en: '{name} and {count} others were removed from the group.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others were removed from the group.", + args: {name: "string", count: "number"} }, groupRemovedTwo: { - en: '{name} and {other_name} were removed from the group.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} were removed from the group.", + args: {name: "string", other_name: "string"} }, groupRemovedYou: { - en: 'You were removed from {group_name}.', - args: { group_name: 'string' }, + en: "You were removed from {group_name}.", + args: {group_name: "string"} }, groupRemovedYouGeneral: { - en: 'You were removed from the group.', - args: undefined, + en: "You were removed from the group.", + args: undefined, }, groupRemovedYouMultiple: { - en: 'You and {count} others were removed from the group.', - args: { count: 'number' }, + en: "You and {count} others were removed from the group.", + args: {count: "number"} }, groupRemovedYouTwo: { - en: 'You and {other_name} were removed from the group.', - args: { other_name: 'string' }, + en: "You and {other_name} were removed from the group.", + args: {other_name: "string"} }, groupSetDisplayPicture: { - en: 'Set Group Display Picture', - args: undefined, + en: "Set Group Display Picture", + args: undefined, }, groupUnknown: { - en: 'Unknown Group', - args: undefined, + en: "Unknown Group", + args: undefined, }, groupUpdated: { - en: 'Group updated', - args: undefined, + en: "Group updated", + args: undefined, }, handlingConnectionCandidates: { - en: 'Handling Connection Candidates', - args: undefined, + en: "Handling Connection Candidates", + args: undefined, }, helpFAQ: { - en: 'FAQ', - args: undefined, + en: "FAQ", + args: undefined, }, helpHelpUsTranslateSession: { - en: 'Help us translate Session', - args: undefined, + en: "Help us translate Session", + args: undefined, }, helpReportABug: { - en: 'Report a bug', - args: undefined, + en: "Report a bug", + args: undefined, }, helpReportABugDescription: { - en: "Share some details to help us resolve your issue. Export your logs, then upload the file through Session's Help Desk.", - args: undefined, + en: "Share some details to help us resolve your issue. Export your logs, then upload the file through Session's Help Desk.", + args: undefined, }, helpReportABugExportLogs: { - en: 'Export Logs', - args: undefined, + en: "Export Logs", + args: undefined, }, helpReportABugExportLogsDescription: { - en: "Export your logs, then upload the file through Session's Help Desk.", - args: undefined, + en: "Export your logs, then upload the file through Session's Help Desk.", + args: undefined, }, helpReportABugExportLogsSaveToDesktop: { - en: 'Save to desktop', - args: undefined, + en: "Save to desktop", + args: undefined, }, helpReportABugExportLogsSaveToDesktopDescription: { - en: 'Save this file to your desktop, then share it with Session developers.', - args: undefined, + en: "Save this file to your desktop, then share it with Session developers.", + args: undefined, }, helpSupport: { - en: 'Support', - args: undefined, + en: "Support", + args: undefined, }, helpWedLoveYourFeedback: { - en: "We'd love your feedback", - args: undefined, + en: "We'd love your feedback", + args: undefined, }, hide: { - en: 'Hide', - args: undefined, + en: "Hide", + args: undefined, }, hideMenuBarDescription: { - en: 'Toggle system menu bar visibility', - args: undefined, + en: "Toggle system menu bar visibility", + args: undefined, + }, + hideNoteToSelfDescription: { + en: "Are you sure you want to hide Note to Self from your conversation list?", + args: undefined, }, hideOthers: { - en: 'Hide Others', - args: undefined, + en: "Hide Others", + args: undefined, }, image: { - en: 'Image', - args: undefined, + en: "Image", + args: undefined, }, images: { - en: 'images', - args: undefined, + en: "images", + args: undefined, }, incognitoKeyboard: { - en: 'Incognito Keyboard', - args: undefined, + en: "Incognito Keyboard", + args: undefined, }, incognitoKeyboardDescription: { - en: 'Request incognito mode if available. Depending on the keyboard you are using, your keyboard may ignore this request.', - args: undefined, + en: "Request incognito mode if available. Depending on the keyboard you are using, your keyboard may ignore this request.", + args: undefined, }, info: { - en: 'Info', - args: undefined, + en: "Info", + args: undefined, }, invalidShortcut: { - en: 'Invalid shortcut', - args: undefined, + en: "Invalid shortcut", + args: undefined, }, join: { - en: 'Join', - args: undefined, + en: "Join", + args: undefined, }, later: { - en: 'Later', - args: undefined, + en: "Later", + args: undefined, }, learnMore: { - en: 'Learn More', - args: undefined, + en: "Learn More", + args: undefined, }, leave: { - en: 'Leave', - args: undefined, + en: "Leave", + args: undefined, }, leaving: { - en: 'Leaving...', - args: undefined, + en: "Leaving...", + args: undefined, }, legacyGroupAfterDeprecationAdmin: { - en: 'This group is now read-only. Recreate this group to keep chatting.', - args: undefined, + en: "This group is now read-only. Recreate this group to keep chatting.", + args: undefined, }, legacyGroupAfterDeprecationMember: { - en: 'This group is now read-only. Ask the group admin to recreate this group to keep chatting.', - args: undefined, + en: "This group is now read-only. Ask the group admin to recreate this group to keep chatting.", + args: undefined, }, legacyGroupBeforeDeprecationAdmin: { - en: 'Groups have been upgraded! Recreate this group for improved reliability. This group will become read-only at {date}.', - args: { date: 'string' }, + en: "Groups have been upgraded! Recreate this group for improved reliability. This group will become read-only at {date}.", + args: {date: "string"} }, legacyGroupBeforeDeprecationMember: { - en: 'Groups have been upgraded! Ask the group admin to recreate this group for improved reliability. This group will become read-only at {date}.', - args: { date: 'string' }, + en: "Groups have been upgraded! Ask the group admin to recreate this group for improved reliability. This group will become read-only at {date}.", + args: {date: "string"} }, legacyGroupChatHistory: { - en: 'Chat history will not be transferred to the new group. You can still view all chat history in your old group.', - args: undefined, + en: "Chat history will not be transferred to the new group. You can still view all chat history in your old group.", + args: undefined, }, legacyGroupMemberNew: { - en: '{name} joined the group.', - args: { name: 'string' }, + en: "{name} joined the group.", + args: {name: "string"} }, legacyGroupMemberNewMultiple: { - en: '{name} and {count} others joined the group.', - args: { name: 'string', count: 'number' }, + en: "{name} and {count} others joined the group.", + args: {name: "string", count: "number"} }, legacyGroupMemberNewYouMultiple: { - en: 'You and {count} others joined the group.', - args: { count: 'number' }, + en: "You and {count} others joined the group.", + args: {count: "number"} }, legacyGroupMemberNewYouOther: { - en: 'You and {other_name} joined the group.', - args: { other_name: 'string' }, + en: "You and {other_name} joined the group.", + args: {other_name: "string"} }, legacyGroupMemberTwoNew: { - en: '{name} and {other_name} joined the group.', - args: { name: 'string', other_name: 'string' }, + en: "{name} and {other_name} joined the group.", + args: {name: "string", other_name: "string"} }, legacyGroupMemberYouNew: { - en: 'You joined the group.', - args: undefined, + en: "You joined the group.", + args: undefined, }, linkPreviews: { - en: 'Link Previews', - args: undefined, + en: "Link Previews", + args: undefined, }, linkPreviewsDescription: { - en: 'Show link previews for supported URLs.', - args: undefined, + en: "Show link previews for supported URLs.", + args: undefined, }, linkPreviewsEnable: { - en: 'Enable Link Previews', - args: undefined, + en: "Enable Link Previews", + args: undefined, }, linkPreviewsErrorLoad: { - en: 'Unable to load link preview', - args: undefined, + en: "Unable to load link preview", + args: undefined, }, linkPreviewsErrorUnsecure: { - en: 'Preview not loaded for unsecure link', - args: undefined, + en: "Preview not loaded for unsecure link", + args: undefined, }, linkPreviewsFirstDescription: { - en: "Display previews for URLs you send and receive. This can be useful, however Session must contact linked websites to generate previews. You can always turn off link previews in Session's settings.", - args: undefined, + en: "Display previews for URLs you send and receive. This can be useful, however Session must contact linked websites to generate previews. You can always turn off link previews in Session's settings.", + args: undefined, }, linkPreviewsSend: { - en: 'Send Link Previews', - args: undefined, + en: "Send Link Previews", + args: undefined, }, linkPreviewsSendModalDescription: { - en: 'You will not have full metadata protection when sending link previews.', - args: undefined, + en: "You will not have full metadata protection when sending link previews.", + args: undefined, }, linkPreviewsTurnedOff: { - en: 'Link Previews Are Off', - args: undefined, + en: "Link Previews Are Off", + args: undefined, }, linkPreviewsTurnedOffDescription: { - en: "Session must contact linked websites to generate previews of links you send and receive.

You can turn them on in Session's settings.", - args: undefined, + en: "Session must contact linked websites to generate previews of links you send and receive.

You can turn them on in Session's settings.", + args: undefined, }, loadAccount: { - en: 'Load Account', - args: undefined, + en: "Load Account", + args: undefined, }, loadAccountProgressMessage: { - en: 'Loading your account', - args: undefined, + en: "Loading your account", + args: undefined, }, loading: { - en: 'Loading...', - args: undefined, + en: "Loading...", + args: undefined, }, lockApp: { - en: 'Lock App', - args: undefined, + en: "Lock App", + args: undefined, }, lockAppDescription: { - en: 'Require fingerprint, PIN, pattern or password to unlock Session.', - args: undefined, + en: "Require fingerprint, PIN, pattern or password to unlock Session.", + args: undefined, }, lockAppDescriptionIos: { - en: 'Require Touch ID, Face ID or your passcode to unlock Session.', - args: undefined, + en: "Require Touch ID, Face ID or your passcode to unlock Session.", + args: undefined, }, lockAppEnablePasscode: { - en: 'You must enable a passcode in your iOS Settings in order to use Screen Lock.', - args: undefined, + en: "You must enable a passcode in your iOS Settings in order to use Screen Lock.", + args: undefined, }, lockAppLocked: { - en: 'Session is locked', - args: undefined, + en: "Session is locked", + args: undefined, }, lockAppQuickResponse: { - en: 'Quick response unavailable when Session is locked!', - args: undefined, + en: "Quick response unavailable when Session is locked!", + args: undefined, }, lockAppStatus: { - en: 'Lock status', - args: undefined, + en: "Lock status", + args: undefined, }, lockAppUnlock: { - en: 'Tap to unlock', - args: undefined, + en: "Tap to unlock", + args: undefined, }, lockAppUnlocked: { - en: 'Session is unlocked', - args: undefined, + en: "Session is unlocked", + args: undefined, }, manageMembers: { - en: 'Manage Members', - args: undefined, + en: "Manage Members", + args: undefined, }, max: { - en: 'Max', - args: undefined, + en: "Max", + args: undefined, }, media: { - en: 'Media', - args: undefined, + en: "Media", + args: undefined, }, membersAddAccountIdOrOns: { - en: 'Add Account ID or ONS', - args: undefined, + en: "Add Account ID or ONS", + args: undefined, }, membersInvite: { - en: 'Invite Contacts', - args: undefined, + en: "Invite Contacts", + args: undefined, }, membersInviteShareDescription: { - en: 'Would you like to share group message history with {name}?', - args: { name: 'string' }, + en: "Would you like to share group message history with {name}?", + args: {name: "string"} }, membersInviteShareDescriptionMultiple: { - en: 'Would you like to share group message history with {name} and {count} others?', - args: { name: 'string', count: 'number' }, + en: "Would you like to share group message history with {name} and {count} others?", + args: {name: "string", count: "number"} }, membersInviteShareDescriptionTwo: { - en: 'Would you like to share group message history with {name} and {other_name}?', - args: { name: 'string', other_name: 'string' }, + en: "Would you like to share group message history with {name} and {other_name}?", + args: {name: "string", other_name: "string"} }, membersInviteShareMessageHistory: { - en: 'Share message history', - args: undefined, + en: "Share message history", + args: undefined, }, membersInviteShareNewMessagesOnly: { - en: 'Share new messages only', - args: undefined, + en: "Share new messages only", + args: undefined, }, membersInviteTitle: { - en: 'Invite', - args: undefined, + en: "Invite", + args: undefined, }, message: { - en: 'Message', - args: undefined, + en: "Message", + args: undefined, + }, + messageBubbleReadMore: { + en: "Read more", + args: undefined, }, messageEmpty: { - en: 'This message is empty.', - args: undefined, + en: "This message is empty.", + args: undefined, }, messageErrorDelivery: { - en: 'Message delivery failed', - args: undefined, + en: "Message delivery failed", + args: undefined, }, messageErrorLimit: { - en: 'Message limit reached', - args: undefined, + en: "Message limit reached", + args: undefined, }, messageErrorOld: { - en: 'Received a message encrypted using an old version of Session that is no longer supported. Please ask the sender to update to the most recent version and resend the message.', - args: undefined, + en: "Received a message encrypted using an old version of Session that is no longer supported. Please ask the sender to update to the most recent version and resend the message.", + args: undefined, }, messageErrorOriginal: { - en: 'Original message not found', - args: undefined, + en: "Original message not found", + args: undefined, }, messageInfo: { - en: 'Message Info', - args: undefined, + en: "Message Info", + args: undefined, }, messageMarkRead: { - en: 'Mark read', - args: undefined, + en: "Mark read", + args: undefined, }, messageMarkUnread: { - en: 'Mark unread', - args: undefined, + en: "Mark unread", + args: undefined, }, messageNewDescriptionDesktop: { - en: "Start a new conversation by entering your friend's Account ID or ONS.", - args: undefined, + en: "Start a new conversation by entering your friend's Account ID or ONS.", + args: undefined, }, messageNewDescriptionMobile: { - en: "Start a new conversation by entering your friend's Account ID, ONS or scanning their QR code.", - args: undefined, + en: "Start a new conversation by entering your friend's Account ID, ONS or scanning their QR code.", + args: undefined, }, messageReplyingTo: { - en: 'Replying to', - args: undefined, + en: "Replying to", + args: undefined, + }, + messageRequestDisabledToastAttachments: { + en: "You cannot send attachments until your Message Request is accepted", + args: undefined, + }, + messageRequestDisabledToastVoiceMessages: { + en: "You cannot send voice messages until your Message Request is accepted", + args: undefined, }, messageRequestGroupInvite: { - en: '{name} invited you to join {group_name}.', - args: { name: 'string', group_name: 'string' }, + en: "{name} invited you to join {group_name}.", + args: {name: "string", group_name: "string"} }, messageRequestGroupInviteDescription: { - en: 'Sending a message to this group will automatically accept the group invite.', - args: undefined, + en: "Sending a message to this group will automatically accept the group invite.", + args: undefined, }, messageRequestPending: { - en: 'Your message request is currently pending.', - args: undefined, + en: "Your message request is currently pending.", + args: undefined, }, messageRequestPendingDescription: { - en: 'You will be able to send voice messages and attachments once the recipient has approved this message request.', - args: undefined, + en: "You will be able to send voice messages and attachments once the recipient has approved this message request.", + args: undefined, }, messageRequestYouHaveAccepted: { - en: 'You have accepted the message request from {name}.', - args: { name: 'string' }, + en: "You have accepted the message request from {name}.", + args: {name: "string"} }, messageRequestsAcceptDescription: { - en: 'Sending a message to this user will automatically accept their message request and reveal your Account ID.', - args: undefined, + en: "Sending a message to this user will automatically accept their message request and reveal your Account ID.", + args: undefined, }, messageRequestsAccepted: { - en: 'Your message request has been accepted.', - args: undefined, + en: "Your message request has been accepted.", + args: undefined, }, messageRequestsClearAllExplanation: { - en: 'Are you sure you want to clear all message requests and group invites?', - args: undefined, + en: "Are you sure you want to clear all message requests and group invites?", + args: undefined, }, messageRequestsCommunities: { - en: 'Community Message Requests', - args: undefined, + en: "Community Message Requests", + args: undefined, }, messageRequestsCommunitiesDescription: { - en: 'Allow message requests from Community conversations.', - args: undefined, + en: "Allow message requests from Community conversations.", + args: undefined, + }, + messageRequestsContactDelete: { + en: "Are you sure you want to delete this message request and the associated contact?", + args: undefined, }, messageRequestsDelete: { - en: 'Are you sure you want to delete this message request?', - args: undefined, + en: "Are you sure you want to delete this message request?", + args: undefined, }, messageRequestsNew: { - en: 'You have a new message request', - args: undefined, + en: "You have a new message request", + args: undefined, }, messageRequestsNonePending: { - en: 'No pending message requests', - args: undefined, + en: "No pending message requests", + args: undefined, }, messageRequestsTurnedOff: { - en: '{name} has message requests from Community conversations turned off, so you cannot send them a message.', - args: { name: 'string' }, + en: "{name} has message requests from Community conversations turned off, so you cannot send them a message.", + args: {name: "string"} }, messageSelect: { - en: 'Select Message', - args: undefined, + en: "Select Message", + args: undefined, }, messageSnippetGroup: { - en: '{author}: {message_snippet}', - args: { author: 'string', message_snippet: 'string' }, + en: "{author}: {message_snippet}", + args: {author: "string", message_snippet: "string"} }, messageStatusFailedToSend: { - en: 'Failed to send', - args: undefined, + en: "Failed to send", + args: undefined, }, messageStatusFailedToSync: { - en: 'Failed to sync', - args: undefined, + en: "Failed to sync", + args: undefined, }, messageStatusSyncing: { - en: 'Syncing', - args: undefined, + en: "Syncing", + args: undefined, }, messageUnread: { - en: 'Unread messages', - args: undefined, + en: "Unread messages", + args: undefined, }, messageVoice: { - en: 'Voice Message', - args: undefined, + en: "Voice Message", + args: undefined, }, messageVoiceErrorShort: { - en: 'Hold to record a voice message', - args: undefined, + en: "Hold to record a voice message", + args: undefined, }, messageVoiceSlideToCancel: { - en: 'Slide to Cancel', - args: undefined, + en: "Slide to Cancel", + args: undefined, }, messageVoiceSnippet: { - en: '{emoji} Voice Message', - args: { emoji: 'string' }, + en: "{emoji} Voice Message", + args: {emoji: "string"} }, messageVoiceSnippetGroup: { - en: '{author}: {emoji} Voice Message', - args: { author: 'string', emoji: 'string' }, + en: "{author}: {emoji} Voice Message", + args: {author: "string", emoji: "string"} }, messages: { - en: 'Messages', - args: undefined, + en: "Messages", + args: undefined, }, minimize: { - en: 'Minimize', - args: undefined, + en: "Minimize", + args: undefined, + }, + modalMessageCharacterDisplayTitle: { + en: "Message Length", + args: undefined, + }, + modalMessageCharacterTooLongDescription: { + en: "You have exceeded the character limit for this message. Please shorten your message to {limit} characters or less.", + args: {limit: "string"} + }, + modalMessageCharacterTooLongTitle: { + en: "Message Too Long", + args: undefined, + }, + modalMessageTooLongDescription: { + en: "Please shorten your message to {limit} characters or less.", + args: {limit: "string"} + }, + modalMessageTooLongTitle: { + en: "Message Too Long", + args: undefined, }, next: { - en: 'Next', - args: undefined, + en: "Next", + args: undefined, }, nicknameDescription: { - en: 'Choose a nickname for {name}. This will appear to you in your one-to-one and group conversations.', - args: { name: 'string' }, + en: "Choose a nickname for {name}. This will appear to you in your one-to-one and group conversations.", + args: {name: "string"} }, nicknameEnter: { - en: 'Enter nickname', - args: undefined, + en: "Enter nickname", + args: undefined, }, nicknameErrorShorter: { - en: 'Please enter a shorter nickname', - args: undefined, + en: "Please enter a shorter nickname", + args: undefined, }, nicknameRemove: { - en: 'Remove Nickname', - args: undefined, + en: "Remove Nickname", + args: undefined, }, nicknameSet: { - en: 'Set Nickname', - args: undefined, + en: "Set Nickname", + args: undefined, }, no: { - en: 'No', - args: undefined, + en: "No", + args: undefined, }, noSuggestions: { - en: 'No Suggestions', - args: undefined, + en: "No Suggestions", + args: undefined, }, none: { - en: 'None', - args: undefined, + en: "None", + args: undefined, }, notNow: { - en: 'Not now', - args: undefined, + en: "Not now", + args: undefined, }, noteToSelf: { - en: 'Note to Self', - args: undefined, + en: "Note to Self", + args: undefined, }, noteToSelfEmpty: { - en: 'You have no messages in Note to Self.', - args: undefined, + en: "You have no messages in Note to Self.", + args: undefined, }, noteToSelfHide: { - en: 'Hide Note to Self', - args: undefined, + en: "Hide Note to Self", + args: undefined, }, noteToSelfHideDescription: { - en: 'Are you sure you want to hide Note to Self?', - args: undefined, + en: "Are you sure you want to hide Note to Self?", + args: undefined, }, notificationsAllMessages: { - en: 'All Messages', - args: undefined, + en: "All Messages", + args: undefined, }, notificationsContent: { - en: 'Notification Content', - args: undefined, + en: "Notification Content", + args: undefined, }, notificationsContentDescription: { - en: 'The information shown in notifications.', - args: undefined, + en: "The information shown in notifications.", + args: undefined, }, notificationsContentShowNameAndContent: { - en: 'Name and Content', - args: undefined, + en: "Name and Content", + args: undefined, }, notificationsContentShowNameOnly: { - en: 'Name Only', - args: undefined, + en: "Name Only", + args: undefined, }, notificationsContentShowNoNameOrContent: { - en: 'No Name or Content', - args: undefined, + en: "No Name or Content", + args: undefined, }, notificationsFastMode: { - en: 'Fast Mode', - args: undefined, + en: "Fast Mode", + args: undefined, }, notificationsFastModeDescription: { - en: "You'll be notified of new messages reliably and immediately using Google's notification Servers.", - args: undefined, + en: "You'll be notified of new messages reliably and immediately using Google's notification Servers.", + args: undefined, }, notificationsFastModeDescriptionHuawei: { - en: "You'll be notified of new messages reliably and immediately using Huawei’s notification servers.", - args: undefined, + en: "You'll be notified of new messages reliably and immediately using Huawei’s notification servers.", + args: undefined, }, notificationsFastModeDescriptionIos: { - en: "You'll be notified of new messages reliably and immediately using Apple's notification Servers.", - args: undefined, + en: "You'll be notified of new messages reliably and immediately using Apple's notification Servers.", + args: undefined, }, notificationsGoToDevice: { - en: 'Go to device notification settings', - args: undefined, + en: "Go to device notification settings", + args: undefined, }, notificationsHeaderAllMessages: { - en: 'Notifications - All', - args: undefined, + en: "Notifications - All", + args: undefined, }, notificationsHeaderMentionsOnly: { - en: 'Notifications - Mentions Only', - args: undefined, + en: "Notifications - Mentions Only", + args: undefined, }, notificationsHeaderMute: { - en: 'Notifications - Muted', - args: undefined, + en: "Notifications - Muted", + args: undefined, }, notificationsIosGroup: { - en: '{name} to {conversation_name}', - args: { name: 'string', conversation_name: 'string' }, + en: "{name} to {conversation_name}", + args: {name: "string", conversation_name: "string"} }, notificationsIosRestart: { - en: 'You may have received messages while your {device} was restarting.', - args: { device: 'string' }, + en: "You may have received messages while your {device} was restarting.", + args: {device: "string"} }, notificationsLedColor: { - en: 'LED color', - args: undefined, + en: "LED color", + args: undefined, }, notificationsMentionsOnly: { - en: 'Mentions Only', - args: undefined, + en: "Mentions Only", + args: undefined, }, notificationsMessage: { - en: 'Message notifications', - args: undefined, + en: "Message notifications", + args: undefined, }, notificationsMostRecent: { - en: 'Most recent from {name}', - args: { name: 'string' }, + en: "Most recent from {name}", + args: {name: "string"} }, notificationsMute: { - en: 'Mute', - args: undefined, + en: "Mute", + args: undefined, }, notificationsMuteFor: { - en: 'Mute for {time_large}', - args: { time_large: 'string' }, + en: "Mute for {time_large}", + args: {time_large: "string"} }, notificationsMuteUnmute: { - en: 'Unmute', - args: undefined, + en: "Unmute", + args: undefined, }, notificationsMuted: { - en: 'Muted', - args: undefined, + en: "Muted", + args: undefined, + }, + notificationsMutedFor: { + en: "Muted for {time_large}", + args: {time_large: "string"} + }, + notificationsMutedForTime: { + en: "Muted until {date_time}", + args: {date_time: "string"} }, notificationsSlowMode: { - en: 'Slow Mode', - args: undefined, + en: "Slow Mode", + args: undefined, }, notificationsSlowModeDescription: { - en: 'Session will occasionally check for new messages in the background.', - args: undefined, + en: "Session will occasionally check for new messages in the background.", + args: undefined, }, notificationsSound: { - en: 'Sound', - args: undefined, + en: "Sound", + args: undefined, }, notificationsSoundDescription: { - en: 'Sound when App is open', - args: undefined, + en: "Sound when App is open", + args: undefined, }, notificationsSoundDesktop: { - en: 'Audio Notifications', - args: undefined, + en: "Audio Notifications", + args: undefined, }, notificationsStrategy: { - en: 'Notification Strategy', - args: undefined, + en: "Notification Strategy", + args: undefined, }, notificationsStyle: { - en: 'Notification Style', - args: undefined, + en: "Notification Style", + args: undefined, }, notificationsSystem: { - en: '{message_count} new messages in {conversation_count} conversations', - args: { message_count: 'string', conversation_count: 'string' }, + en: "{message_count} new messages in {conversation_count} conversations", + args: {message_count: "string", conversation_count: "string"} }, notificationsVibrate: { - en: 'Vibrate', - args: undefined, + en: "Vibrate", + args: undefined, }, off: { - en: 'Off', - args: undefined, + en: "Off", + args: undefined, }, okay: { - en: 'Okay', - args: undefined, + en: "Okay", + args: undefined, }, on: { - en: 'On', - args: undefined, + en: "On", + args: undefined, }, onboardingAccountCreate: { - en: 'Create account', - args: undefined, + en: "Create account", + args: undefined, }, onboardingAccountCreated: { - en: 'Account Created', - args: undefined, + en: "Account Created", + args: undefined, }, onboardingAccountExists: { - en: 'I have an account', - args: undefined, + en: "I have an account", + args: undefined, }, onboardingBackAccountCreation: { - en: 'You cannot go back further. In order to cancel your account creation, Session needs to quit.', - args: undefined, + en: "You cannot go back further. In order to cancel your account creation, Session needs to quit.", + args: undefined, }, onboardingBackLoadAccount: { - en: 'You cannot go back further. In order to stop loading your account, Session needs to quit.', - args: undefined, + en: "You cannot go back further. In order to stop loading your account, Session needs to quit.", + args: undefined, }, onboardingBubbleCreatingAnAccountIsEasy: { - en: 'Creating an account is instant, free, and anonymous {emoji}', - args: { emoji: 'string' }, + en: "Creating an account is instant, free, and anonymous {emoji}", + args: {emoji: "string"} }, onboardingBubbleNoPhoneNumber: { - en: "You don't even need a phone number to sign up.", - args: undefined, + en: "You don't even need a phone number to sign up.", + args: undefined, }, onboardingBubblePrivacyInYourPocket: { - en: 'Privacy in your pocket.', - args: undefined, + en: "Privacy in your pocket.", + args: undefined, }, onboardingBubbleSessionIsEngineered: { - en: 'Session is engineered to protect your privacy.', - args: undefined, + en: "Session is engineered to protect your privacy.", + args: undefined, }, onboardingBubbleWelcomeToSession: { - en: 'Welcome to Session {emoji}', - args: { emoji: 'string' }, + en: "Welcome to Session {emoji}", + args: {emoji: "string"} }, onboardingHitThePlusButton: { - en: 'Hit the plus button to start a chat, create a group, or join an official community!', - args: undefined, + en: "Hit the plus button to start a chat, create a group, or join an official community!", + args: undefined, }, onboardingMessageNotificationExplanation: { - en: 'There are two ways Session can notify you of new messages.', - args: undefined, + en: "There are two ways Session can notify you of new messages.", + args: undefined, }, onboardingPrivacy: { - en: 'Privacy Policy', - args: undefined, + en: "Privacy Policy", + args: undefined, }, onboardingTos: { - en: 'Terms of Service', - args: undefined, + en: "Terms of Service", + args: undefined, }, onboardingTosPrivacy: { - en: 'By using this service, you agree to our Terms of Service and Privacy Policy', - args: undefined, + en: "By using this service, you agree to our Terms of Service and Privacy Policy", + args: undefined, }, onionRoutingPath: { - en: 'Path', - args: undefined, + en: "Path", + args: undefined, }, onionRoutingPathDescription: { - en: "Session hides your IP by routing your messages through multiple service nodes in Session's decentralized network. This is your current path:", - args: undefined, + en: "Session hides your IP by routing your messages through multiple service nodes in Session's decentralized network. This is your current path:", + args: undefined, }, onionRoutingPathDestination: { - en: 'Destination', - args: undefined, + en: "Destination", + args: undefined, }, onionRoutingPathEntryNode: { - en: 'Entry Node', - args: undefined, + en: "Entry Node", + args: undefined, }, onionRoutingPathServiceNode: { - en: 'Service Node', - args: undefined, + en: "Service Node", + args: undefined, }, onionRoutingPathUnknownCountry: { - en: 'Unknown Country', - args: undefined, + en: "Unknown Country", + args: undefined, }, onsErrorNotRecognized: { - en: "We couldn't recognize this ONS. Please check it and try again.", - args: undefined, + en: "We couldn't recognize this ONS. Please check it and try again.", + args: undefined, }, onsErrorUnableToSearch: { - en: 'We were unable to search for this ONS. Please try again later.', - args: undefined, + en: "We were unable to search for this ONS. Please try again later.", + args: undefined, }, open: { - en: 'Open', - args: undefined, + en: "Open", + args: undefined, }, other: { - en: 'Other', - args: undefined, + en: "Other", + args: undefined, }, passwordChange: { - en: 'Change Password', - args: undefined, + en: "Change Password", + args: undefined, }, passwordChangeDescription: { - en: 'Change the password required to unlock Session.', - args: undefined, + en: "Change the password required to unlock Session.", + args: undefined, }, passwordChangedDescription: { - en: 'Your password has been changed. Please keep it safe.', - args: undefined, + en: "Your password has been changed. Please keep it safe.", + args: undefined, }, passwordConfirm: { - en: 'Confirm password', - args: undefined, + en: "Confirm password", + args: undefined, }, passwordCreate: { - en: 'Create your password', - args: undefined, + en: "Create your password", + args: undefined, }, passwordCurrentIncorrect: { - en: 'Your current password is incorrect.', - args: undefined, + en: "Your current password is incorrect.", + args: undefined, }, passwordDescription: { - en: 'Require password to unlock Session.', - args: undefined, + en: "Require password to unlock Session.", + args: undefined, }, passwordEnter: { - en: 'Enter password', - args: undefined, + en: "Enter password", + args: undefined, }, passwordEnterCurrent: { - en: 'Please enter your current password', - args: undefined, + en: "Please enter your current password", + args: undefined, }, passwordEnterNew: { - en: 'Please enter your new password', - args: undefined, + en: "Please enter your new password", + args: undefined, }, passwordError: { - en: 'Password must only contain letters, numbers and symbols', - args: undefined, + en: "Password must only contain letters, numbers and symbols", + args: undefined, }, passwordErrorLength: { - en: 'Password must be between 6 and 64 characters long', - args: undefined, + en: "Password must be between 6 and 64 characters long", + args: undefined, }, passwordErrorMatch: { - en: 'Passwords do not match', - args: undefined, + en: "Passwords do not match", + args: undefined, }, passwordFailed: { - en: 'Failed to set password', - args: undefined, + en: "Failed to set password", + args: undefined, }, passwordIncorrect: { - en: 'Incorrect password', - args: undefined, + en: "Incorrect password", + args: undefined, }, passwordRemove: { - en: 'Remove Password', - args: undefined, + en: "Remove Password", + args: undefined, }, passwordRemoveDescription: { - en: 'Remove the password required to unlock Session.', - args: undefined, + en: "Remove the password required to unlock Session.", + args: undefined, }, passwordRemovedDescription: { - en: 'Your password has been removed.', - args: undefined, + en: "Your password has been removed.", + args: undefined, }, passwordSet: { - en: 'Set Password', - args: undefined, + en: "Set Password", + args: undefined, }, passwordSetDescription: { - en: 'Your password has been set. Please keep it safe.', - args: undefined, + en: "Your password has been set. Please keep it safe.", + args: undefined, }, paste: { - en: 'Paste', - args: undefined, + en: "Paste", + args: undefined, }, permissionChange: { - en: 'Permission Change', - args: undefined, + en: "Permission Change", + args: undefined, }, permissionMusicAudioDenied: { - en: 'Session needs music and audio access in order to send files, music and audio, but it has been permanently denied. Tap Settings → Permissions, and turn "Music and audio" on.', - args: undefined, + en: "Session needs music and audio access in order to send files, music and audio, but it has been permanently denied. Tap Settings → Permissions, and turn \"Music and audio\" on.", + args: undefined, }, permissionsAppleMusic: { - en: 'Session needs to use Apple Music to play media attachments.', - args: undefined, + en: "Session needs to use Apple Music to play media attachments.", + args: undefined, }, permissionsAutoUpdate: { - en: 'Auto Update', - args: undefined, + en: "Auto Update", + args: undefined, }, permissionsAutoUpdateDescription: { - en: 'Automatically check for updates on startup.', - args: undefined, + en: "Automatically check for updates on startup.", + args: undefined, }, permissionsCameraAccessRequiredCallsIos: { - en: 'Camera access is required to make video calls. Toggle the "Camera" permission in Settings to continue.', - args: undefined, + en: "Camera access is required to make video calls. Toggle the \"Camera\" permission in Settings to continue.", + args: undefined, }, permissionsCameraChangeDescriptionIos: { - en: 'Camera access is currently enabled. To disable it, toggle the "Camera" permission in Settings.', - args: undefined, + en: "Camera access is currently enabled. To disable it, toggle the \"Camera\" permission in Settings.", + args: undefined, }, permissionsCameraDenied: { - en: 'Session needs camera access to take photos and videos, but it has been permanently denied. Tap Settings → Permissions, and turn "Camera" on.', - args: undefined, + en: "Session needs camera access to take photos and videos, but it has been permanently denied. Tap Settings → Permissions, and turn \"Camera\" on.", + args: undefined, }, permissionsCameraDescriptionIos: { - en: 'Allow access to camera for video calls.', - args: undefined, + en: "Allow access to camera for video calls.", + args: undefined, }, permissionsFaceId: { - en: 'The screen lock feature on Session uses Face ID.', - args: undefined, + en: "The screen lock feature on Session uses Face ID.", + args: undefined, }, permissionsKeepInSystemTray: { - en: 'Keep in System Tray', - args: undefined, + en: "Keep in System Tray", + args: undefined, }, permissionsKeepInSystemTrayDescription: { - en: 'Session continues running in the background when you close the window', - args: undefined, + en: "Session continues running in the background when you close the window", + args: undefined, }, permissionsLibrary: { - en: 'Session needs photo library access to continue. You can enable access in the iOS settings.', - args: undefined, + en: "Session needs photo library access to continue. You can enable access in the iOS settings.", + args: undefined, }, permissionsLocalNetworkAccessRequiredCallsIos: { - en: 'Local Network access is required to facilitate calls. Toggle the "Local Network" permission in Settings to continue.', - args: undefined, + en: "Local Network access is required to facilitate calls. Toggle the \"Local Network\" permission in Settings to continue.", + args: undefined, }, permissionsLocalNetworkAccessRequiredIos: { - en: 'Session needs access to local network to make voice and video calls.', - args: undefined, + en: "Session needs access to local network to make voice and video calls.", + args: undefined, }, permissionsLocalNetworkChangeDescriptionIos: { - en: 'Local Network access is currently enabled. To disable it, toggle the "Local Network" permission in Settings.', - args: undefined, + en: "Local Network access is currently enabled. To disable it, toggle the \"Local Network\" permission in Settings.", + args: undefined, }, permissionsLocalNetworkDescriptionIos: { - en: 'Allow access to local network to facilitate voice and video calls.', - args: undefined, + en: "Allow access to local network to facilitate voice and video calls.", + args: undefined, }, permissionsLocalNetworkIos: { - en: 'Local Network', - args: undefined, + en: "Local Network", + args: undefined, }, permissionsMicrophone: { - en: 'Microphone', - args: undefined, + en: "Microphone", + args: undefined, }, permissionsMicrophoneAccessRequired: { - en: 'Session needs microphone access to make calls and send audio messages, but it has been permanently denied. Tap settings → Permissions, and turn "Microphone" on.', - args: undefined, + en: "Session needs microphone access to make calls and send audio messages, but it has been permanently denied. Tap settings → Permissions, and turn \"Microphone\" on.", + args: undefined, }, permissionsMicrophoneAccessRequiredCallsIos: { - en: 'Microphone access is required to make calls and record audio messages. Toggle the "Microphone" permission in Settings to continue.', - args: undefined, + en: "Microphone access is required to make calls and record audio messages. Toggle the \"Microphone\" permission in Settings to continue.", + args: undefined, }, permissionsMicrophoneAccessRequiredDesktop: { - en: "You can enable microphone access in Session's privacy settings", - args: undefined, + en: "You can enable microphone access in Session's privacy settings", + args: undefined, }, permissionsMicrophoneAccessRequiredIos: { - en: 'Session needs microphone access to make calls and record audio messages.', - args: undefined, + en: "Session needs microphone access to make calls and record audio messages.", + args: undefined, }, permissionsMicrophoneChangeDescriptionIos: { - en: 'Microphone access is currently enabled. To disable it, toggle the "Microphone" permission in Settings.', - args: undefined, + en: "Microphone access is currently enabled. To disable it, toggle the \"Microphone\" permission in Settings.", + args: undefined, }, permissionsMicrophoneDescription: { - en: 'Allow access to microphone.', - args: undefined, + en: "Allow access to microphone.", + args: undefined, }, permissionsMicrophoneDescriptionIos: { - en: 'Allow access to microphone for voice calls and audio messages.', - args: undefined, + en: "Allow access to microphone for voice calls and audio messages.", + args: undefined, }, permissionsMusicAudio: { - en: 'Session needs music and audio access in order to send files, music and audio.', - args: undefined, + en: "Session needs music and audio access in order to send files, music and audio.", + args: undefined, }, permissionsRequired: { - en: 'Permission Required', - args: undefined, + en: "Permission Required", + args: undefined, }, permissionsStorageDenied: { - en: 'Session needs photo library access so you can send photos and videos, but it has been permanently denied. Tap Settings → Permissions, and turn "Photos and videos" on.', - args: undefined, + en: "Session needs photo library access so you can send photos and videos, but it has been permanently denied. Tap Settings → Permissions, and turn \"Photos and videos\" on.", + args: undefined, }, permissionsStorageDeniedLegacy: { - en: 'Session needs storage access so you can send and save attachments. Tap Settings → Permissions, and turn "Storage" on.', - args: undefined, + en: "Session needs storage access so you can send and save attachments. Tap Settings → Permissions, and turn \"Storage\" on.", + args: undefined, }, permissionsStorageSave: { - en: 'Session needs storage access to save attachments and media.', - args: undefined, + en: "Session needs storage access to save attachments and media.", + args: undefined, }, permissionsStorageSaveDenied: { - en: 'Session needs storage access to save photos and videos, but it has been permanently denied. Please continue to app settings, select "Permissions", and enable "Storage".', - args: undefined, + en: "Session needs storage access to save photos and videos, but it has been permanently denied. Please continue to app settings, select \"Permissions\", and enable \"Storage\".", + args: undefined, }, permissionsStorageSend: { - en: 'Session needs storage access to send photos and videos.', - args: undefined, + en: "Session needs storage access to send photos and videos.", + args: undefined, + }, + permissionsWriteCommunity: { + en: "You don't have write permissions in this community", + args: undefined, }, pin: { - en: 'Pin', - args: undefined, + en: "Pin", + args: undefined, }, pinConversation: { - en: 'Pin Conversation', - args: undefined, + en: "Pin Conversation", + args: undefined, }, pinUnpin: { - en: 'Unpin', - args: undefined, + en: "Unpin", + args: undefined, }, pinUnpinConversation: { - en: 'Unpin Conversation', - args: undefined, + en: "Unpin Conversation", + args: undefined, }, preview: { - en: 'Preview', - args: undefined, + en: "Preview", + args: undefined, }, profile: { - en: 'Profile', - args: undefined, + en: "Profile", + args: undefined, }, profileDisplayPicture: { - en: 'Display Picture', - args: undefined, + en: "Display Picture", + args: undefined, }, profileDisplayPictureRemoveError: { - en: 'Failed to remove display picture.', - args: undefined, + en: "Failed to remove display picture.", + args: undefined, }, profileDisplayPictureSet: { - en: 'Set Display Picture', - args: undefined, + en: "Set Display Picture", + args: undefined, }, profileDisplayPictureSizeError: { - en: 'Please pick a smaller file.', - args: undefined, + en: "Please pick a smaller file.", + args: undefined, }, profileErrorUpdate: { - en: 'Failed to update profile.', - args: undefined, + en: "Failed to update profile.", + args: undefined, }, promote: { - en: 'Promote', - args: undefined, + en: "Promote", + args: undefined, }, qrCode: { - en: 'QR Code', - args: undefined, + en: "QR Code", + args: undefined, }, qrNotAccountId: { - en: 'This QR code does not contain an Account ID', - args: undefined, + en: "This QR code does not contain an Account ID", + args: undefined, }, qrNotRecoveryPassword: { - en: 'This QR code does not contain a Recovery Password', - args: undefined, + en: "This QR code does not contain a Recovery Password", + args: undefined, }, qrScan: { - en: 'Scan QR Code', - args: undefined, + en: "Scan QR Code", + args: undefined, }, qrView: { - en: 'View QR', - args: undefined, + en: "View QR", + args: undefined, }, qrYoursDescription: { - en: 'Friends can message you by scanning your QR code.', - args: undefined, + en: "Friends can message you by scanning your QR code.", + args: undefined, }, quit: { - en: 'Quit Session', - args: undefined, + en: "Quit Session", + args: undefined, }, quitButton: { - en: 'Quit', - args: undefined, + en: "Quit", + args: undefined, }, read: { - en: 'Read', - args: undefined, + en: "Read", + args: undefined, }, readReceipts: { - en: 'Read Receipts', - args: undefined, + en: "Read Receipts", + args: undefined, }, readReceiptsDescription: { - en: 'Show read receipts for all messages you send and receive.', - args: undefined, + en: "Show read receipts for all messages you send and receive.", + args: undefined, }, received: { - en: 'Received:', - args: undefined, + en: "Received:", + args: undefined, }, receivedAnswer: { - en: 'Received Answer', - args: undefined, + en: "Received Answer", + args: undefined, }, receivingCallOffer: { - en: 'Receiving Call Offer', - args: undefined, + en: "Receiving Call Offer", + args: undefined, }, receivingPreOffer: { - en: 'Receiving Pre Offer', - args: undefined, + en: "Receiving Pre Offer", + args: undefined, }, recommended: { - en: 'Recommended', - args: undefined, + en: "Recommended", + args: undefined, }, recoveryPasswordBannerDescription: { - en: "Save your recovery password to make sure you don't lose access to your account.", - args: undefined, + en: "Save your recovery password to make sure you don't lose access to your account.", + args: undefined, }, recoveryPasswordBannerTitle: { - en: 'Save your recovery password', - args: undefined, + en: "Save your recovery password", + args: undefined, }, recoveryPasswordDescription: { - en: "Use your recovery password to load your account on new devices.

Your account cannot be recovered without your recovery password. Make sure it's stored somewhere safe and secure — and don't share it with anyone.", - args: undefined, + en: "Use your recovery password to load your account on new devices.

Your account cannot be recovered without your recovery password. Make sure it's stored somewhere safe and secure — and don't share it with anyone.", + args: undefined, }, recoveryPasswordEnter: { - en: 'Enter your recovery password', - args: undefined, + en: "Enter your recovery password", + args: undefined, }, recoveryPasswordErrorLoad: { - en: 'An error occurred when trying to load your recovery password.

Please export your logs, then upload the file through the Session Help Desk to help resolve this issue.', - args: undefined, + en: "An error occurred when trying to load your recovery password.

Please export your logs, then upload the file through the Session Help Desk to help resolve this issue.", + args: undefined, }, recoveryPasswordErrorMessageGeneric: { - en: 'Please check your recovery password and try again.', - args: undefined, + en: "Please check your recovery password and try again.", + args: undefined, }, recoveryPasswordErrorMessageIncorrect: { - en: 'Some of the words in your Recovery Password are incorrect. Please check and try again.', - args: undefined, + en: "Some of the words in your Recovery Password are incorrect. Please check and try again.", + args: undefined, }, recoveryPasswordErrorMessageShort: { - en: 'The Recovery Password you entered is not long enough. Please check and try again.', - args: undefined, + en: "The Recovery Password you entered is not long enough. Please check and try again.", + args: undefined, }, recoveryPasswordErrorTitle: { - en: 'Incorrect Recovery Password', - args: undefined, + en: "Incorrect Recovery Password", + args: undefined, }, recoveryPasswordExplanation: { - en: 'To load your account, enter your recovery password.', - args: undefined, + en: "To load your account, enter your recovery password.", + args: undefined, }, recoveryPasswordHidePermanently: { - en: 'Hide Recovery Password Permanently', - args: undefined, + en: "Hide Recovery Password Permanently", + args: undefined, }, recoveryPasswordHidePermanentlyDescription1: { - en: 'Without your recovery password, you cannot load your account on new devices.

We strongly recommend you save your recovery password in a safe and secure place before continuing.', - args: undefined, + en: "Without your recovery password, you cannot load your account on new devices.

We strongly recommend you save your recovery password in a safe and secure place before continuing.", + args: undefined, }, recoveryPasswordHidePermanentlyDescription2: { - en: 'Are you sure you want to permanently hide your recovery password on this device? This cannot be undone.', - args: undefined, + en: "Are you sure you want to permanently hide your recovery password on this device? This cannot be undone.", + args: undefined, }, recoveryPasswordHideRecoveryPassword: { - en: 'Hide Recovery Password', - args: undefined, + en: "Hide Recovery Password", + args: undefined, }, recoveryPasswordHideRecoveryPasswordDescription: { - en: 'Permanently hide your recovery password on this device.', - args: undefined, + en: "Permanently hide your recovery password on this device.", + args: undefined, }, recoveryPasswordRestoreDescription: { - en: "Enter your recovery password to load your account. If you haven't saved it, you can find it in your app settings.", - args: undefined, + en: "Enter your recovery password to load your account. If you haven't saved it, you can find it in your app settings.", + args: undefined, }, recoveryPasswordView: { - en: 'View Password', - args: undefined, + en: "View Password", + args: undefined, }, recoveryPasswordWarningSendDescription: { - en: "This is your recovery password. If you send it to someone they'll have full access to your account.", - args: undefined, + en: "This is your recovery password. If you send it to someone they'll have full access to your account.", + args: undefined, }, recreateGroup: { - en: 'Recreate Group', - args: undefined, + en: "Recreate Group", + args: undefined, }, redo: { - en: 'Redo', - args: undefined, + en: "Redo", + args: undefined, + }, + remainingCharactersOverTooltip: { + en: "Reduce message length by {count}", + args: {count: "number"} }, remove: { - en: 'Remove', - args: undefined, + en: "Remove", + args: undefined, }, removePasswordFail: { - en: 'Failed to remove password', - args: undefined, + en: "Failed to remove password", + args: undefined, }, reply: { - en: 'Reply', - args: undefined, + en: "Reply", + args: undefined, }, resend: { - en: 'Resend', - args: undefined, + en: "Resend", + args: undefined, }, resolving: { - en: 'Loading country information...', - args: undefined, + en: "Loading country information...", + args: undefined, }, restart: { - en: 'Restart', - args: undefined, + en: "Restart", + args: undefined, }, resync: { - en: 'Resync', - args: undefined, + en: "Resync", + args: undefined, }, retry: { - en: 'Retry', - args: undefined, + en: "Retry", + args: undefined, }, save: { - en: 'Save', - args: undefined, + en: "Save", + args: undefined, }, saved: { - en: 'Saved', - args: undefined, + en: "Saved", + args: undefined, }, savedMessages: { - en: 'Saved messages', - args: undefined, + en: "Saved messages", + args: undefined, }, saving: { - en: 'Saving...', - args: undefined, + en: "Saving...", + args: undefined, }, scan: { - en: 'Scan', - args: undefined, + en: "Scan", + args: undefined, }, screenSecurity: { - en: 'Screen Security', - args: undefined, + en: "Screen Security", + args: undefined, }, screenshotNotifications: { - en: 'Screenshot Notifications', - args: undefined, + en: "Screenshot Notifications", + args: undefined, }, screenshotNotificationsDescription: { - en: 'Require a notification when a contact takes a screenshot of a one-to-one chat.', - args: undefined, + en: "Require a notification when a contact takes a screenshot of a one-to-one chat.", + args: undefined, }, screenshotTaken: { - en: '{name} took a screenshot.', - args: { name: 'string' }, + en: "{name} took a screenshot.", + args: {name: "string"} }, search: { - en: 'Search', - args: undefined, + en: "Search", + args: undefined, }, searchContacts: { - en: 'Search Contacts', - args: undefined, + en: "Search Contacts", + args: undefined, }, searchConversation: { - en: 'Search Conversation', - args: undefined, + en: "Search Conversation", + args: undefined, }, searchEnter: { - en: 'Please enter your search.', - args: undefined, + en: "Please enter your search.", + args: undefined, }, searchMatchesNone: { - en: 'No results found.', - args: undefined, + en: "No results found.", + args: undefined, }, searchMatchesNoneSpecific: { - en: 'No results found for {query}', - args: { query: 'string' }, + en: "No results found for {query}", + args: {query: "string"} }, searchMembers: { - en: 'Search Members', - args: undefined, + en: "Search Members", + args: undefined, }, searchSearching: { - en: 'Searching...', - args: undefined, + en: "Searching...", + args: undefined, }, select: { - en: 'Select', - args: undefined, + en: "Select", + args: undefined, }, selectAll: { - en: 'Select All', - args: undefined, + en: "Select All", + args: undefined, + }, + selectAppIcon: { + en: "Select app icon", + args: undefined, }, send: { - en: 'Send', - args: undefined, + en: "Send", + args: undefined, }, sending: { - en: 'Sending', - args: undefined, + en: "Sending", + args: undefined, }, sendingCallOffer: { - en: 'Sending Call Offer', - args: undefined, + en: "Sending Call Offer", + args: undefined, }, sendingConnectionCandidates: { - en: 'Sending Connection Candidates', - args: undefined, + en: "Sending Connection Candidates", + args: undefined, }, sent: { - en: 'Sent:', - args: undefined, + en: "Sent:", + args: undefined, }, sessionAppearance: { - en: 'Appearance', - args: undefined, + en: "Appearance", + args: undefined, }, sessionClearData: { - en: 'Clear Data', - args: undefined, + en: "Clear Data", + args: undefined, }, sessionConversations: { - en: 'Conversations', - args: undefined, + en: "Conversations", + args: undefined, }, sessionHelp: { - en: 'Help', - args: undefined, + en: "Help", + args: undefined, }, sessionInviteAFriend: { - en: 'Invite a Friend', - args: undefined, + en: "Invite a Friend", + args: undefined, }, sessionMessageRequests: { - en: 'Message Requests', - args: undefined, + en: "Message Requests", + args: undefined, + }, + sessionNetworkCurrentPrice: { + en: "Current SESH price", + args: undefined, + }, + sessionNetworkDescription: { + en: "Messages are sent using the Session Network. The network is comprised of nodes incentivized with Session Token, which keeps Session decentralized and secure. Learn More {icon}", + args: {icon: "string"} + }, + sessionNetworkLearnAboutStaking: { + en: "Learn About Staking", + args: undefined, + }, + sessionNetworkMarketCap: { + en: "Market Cap", + args: undefined, + }, + sessionNetworkNodesSecuring: { + en: "Session Nodes securing your messages", + args: undefined, + }, + sessionNetworkNodesSwarm: { + en: "Session Nodes in your swarm", + args: undefined, + }, + sessionNetworkNotificationLive: { + en: "Session Token is live! Explore the new Session Network section in Settings to learn how Session Token powers Session.", + args: undefined, + }, + sessionNetworkSecuredBy: { + en: "Network secured by", + args: undefined, + }, + sessionNetworkTokenDescription: { + en: "When you stake Session Token to secure the network, you earn rewards in SESH from the Staking Reward Pool.", + args: undefined, + }, + sessionNew: { + en: " New", + args: undefined, }, sessionNotifications: { - en: 'Notifications', - args: undefined, + en: "Notifications", + args: undefined, }, sessionPermissions: { - en: 'Permissions', - args: undefined, + en: "Permissions", + args: undefined, }, sessionPrivacy: { - en: 'Privacy', - args: undefined, + en: "Privacy", + args: undefined, }, sessionRecoveryPassword: { - en: 'Recovery Password', - args: undefined, + en: "Recovery Password", + args: undefined, }, sessionSettings: { - en: 'Settings', - args: undefined, + en: "Settings", + args: undefined, }, set: { - en: 'Set', - args: undefined, + en: "Set", + args: undefined, + }, + setCommunityDisplayPicture: { + en: "Set Community Display Picture", + args: undefined, }, settingsRestartDescription: { - en: 'You must restart Session to apply your new settings.', - args: undefined, + en: "You must restart Session to apply your new settings.", + args: undefined, }, share: { - en: 'Share', - args: undefined, + en: "Share", + args: undefined, }, shareAccountIdDescription: { - en: 'Invite your friend to chat with you on Session by sharing your Account ID with them.', - args: undefined, + en: "Invite your friend to chat with you on Session by sharing your Account ID with them.", + args: undefined, }, shareAccountIdDescriptionCopied: { - en: 'Share with your friends wherever you usually speak with them — then move the conversation here.', - args: undefined, + en: "Share with your friends wherever you usually speak with them — then move the conversation here.", + args: undefined, }, shareExtensionDatabaseError: { - en: 'There is an issue opening the database. Please restart the app and try again.', - args: undefined, + en: "There is an issue opening the database. Please restart the app and try again.", + args: undefined, }, shareExtensionNoAccountError: { - en: "Oops! Looks like you don't have a Session account yet.

You'll need to create one in the Session app before you can share.", - args: undefined, + en: "Oops! Looks like you don't have a Session account yet.

You'll need to create one in the Session app before you can share.", + args: undefined, }, shareToSession: { - en: 'Share to Session', - args: undefined, + en: "Share to Session", + args: undefined, }, show: { - en: 'Show', - args: undefined, + en: "Show", + args: undefined, }, showAll: { - en: 'Show All', - args: undefined, + en: "Show All", + args: undefined, }, showLess: { - en: 'Show Less', - args: undefined, + en: "Show Less", + args: undefined, + }, + showNoteToSelf: { + en: "Show Note to Self", + args: undefined, + }, + showNoteToSelfDescription: { + en: "Are you sure you want to show Note to Self in your conversation list?", + args: undefined, }, stickers: { - en: 'Stickers', - args: undefined, + en: "Stickers", + args: undefined, }, supportGoTo: { - en: 'Go to Support Page', - args: undefined, + en: "Go to Support Page", + args: undefined, }, systemInformationDesktop: { - en: 'System Information: {information}', - args: { information: 'string' }, + en: "System Information: {information}", + args: {information: "string"} }, tapToRetry: { - en: 'Tap to retry', - args: undefined, + en: "Tap to retry", + args: undefined, }, theContinue: { - en: 'Continue', - args: undefined, + en: "Continue", + args: undefined, }, theDefault: { - en: 'Default', - args: undefined, + en: "Default", + args: undefined, }, theError: { - en: 'Error', - args: undefined, + en: "Error", + args: undefined, }, tryAgain: { - en: 'Try Again', - args: undefined, + en: "Try Again", + args: undefined, }, typingIndicators: { - en: 'Typing Indicators', - args: undefined, + en: "Typing Indicators", + args: undefined, }, typingIndicatorsDescription: { - en: 'See and share typing indicators.', - args: undefined, + en: "See and share typing indicators.", + args: undefined, + }, + unavailable: { + en: "Unavailable", + args: undefined, }, undo: { - en: 'Undo', - args: undefined, + en: "Undo", + args: undefined, }, unknown: { - en: 'Unknown', - args: undefined, + en: "Unknown", + args: undefined, }, updateApp: { - en: 'App updates', - args: undefined, + en: "App updates", + args: undefined, }, updateDownloaded: { - en: 'Update installed, click to restart', - args: undefined, + en: "Update installed, click to restart", + args: undefined, }, updateDownloading: { - en: 'Downloading update: {percent_loader}%', - args: { percent_loader: 'string' }, + en: "Downloading update: {percent_loader}%", + args: {percent_loader: "string"} }, updateError: { - en: 'Cannot Update', - args: undefined, + en: "Cannot Update", + args: undefined, }, updateErrorDescription: { - en: 'Session failed to update. Please go to https://getsession.org/download and install the new version manually, then contact our Help Center to let us know about this problem.', - args: undefined, + en: "Session failed to update. Please go to https://getsession.org/download and install the new version manually, then contact our Help Center to let us know about this problem.", + args: undefined, + }, + updateGroupInformation: { + en: "Update Group Information", + args: undefined, + }, + updateGroupInformationDescription: { + en: "Group name and description are visible to all group members.", + args: undefined, + }, + updateGroupInformationEnterShorterDescription: { + en: "Please enter a shorter group description", + args: undefined, }, updateNewVersion: { - en: 'A new version of Session is available, tap to update', - args: undefined, + en: "A new version of Session is available, tap to update", + args: undefined, }, updateNewVersionDescription: { - en: 'A new version ({version}) of Session is available.', - args: { version: 'string' }, + en: "A new version ({version}) of Session is available.", + args: {version: "string"} }, updateReleaseNotes: { - en: 'Go to Release Notes', - args: undefined, + en: "Go to Release Notes", + args: undefined, }, updateSession: { - en: 'Session Update', - args: undefined, + en: "Session Update", + args: undefined, }, updateVersion: { - en: 'Version {version}', - args: { version: 'string' }, + en: "Version {version}", + args: {version: "string"} + }, + updated: { + en: "Last updated {relative_time} ago", + args: {relative_time: "string"} }, uploading: { - en: 'Uploading', - args: undefined, + en: "Uploading", + args: undefined, }, urlCopy: { - en: 'Copy URL', - args: undefined, + en: "Copy URL", + args: undefined, }, urlOpen: { - en: 'Open URL', - args: undefined, + en: "Open URL", + args: undefined, }, urlOpenBrowser: { - en: 'This will open in your browser.', - args: undefined, + en: "This will open in your browser.", + args: undefined, }, urlOpenDescription: { - en: 'Are you sure you want to open this URL in your browser?

{url}', - args: { url: 'string' }, + en: "Are you sure you want to open this URL in your browser?

{url}", + args: {url: "string"} }, useFastMode: { - en: 'Use Fast Mode', - args: undefined, + en: "Use Fast Mode", + args: undefined, }, video: { - en: 'Video', - args: undefined, + en: "Video", + args: undefined, }, videoErrorPlay: { - en: 'Unable to play video.', - args: undefined, + en: "Unable to play video.", + args: undefined, }, view: { - en: 'View', - args: undefined, + en: "View", + args: undefined, }, viewLess: { - en: 'View Less', - args: undefined, + en: "View Less", + args: undefined, }, viewMore: { - en: 'View More', - args: undefined, + en: "View More", + args: undefined, }, waitFewMinutes: { - en: 'This can take a few minutes.', - args: undefined, + en: "This can take a few minutes.", + args: undefined, }, waitOneMoment: { - en: 'One moment please...', - args: undefined, + en: "One moment please...", + args: undefined, }, warning: { - en: 'Warning', - args: undefined, + en: "Warning", + args: undefined, }, window: { - en: 'Window', - args: undefined, + en: "Window", + args: undefined, }, yes: { - en: 'Yes', - args: undefined, + en: "Yes", + args: undefined, }, you: { - en: 'You', - args: undefined, + en: "You", + args: undefined, + }, + sessionNetworkDataPrice: { + en: "Price data powered by CoinGecko
Accurate at {date_time}", + args: {date_time: "string"} }, } as const; export const pluralsDictionary = { adminSendingPromotion: { - en: { - one: 'Sending admin promotion', - other: 'Sending admin promotions', + en:{ + one: "Sending admin promotion", + other: "Sending admin promotions" }, - args: { count: 'number' }, + args: {count: "number"} }, clearDataErrorDescription: { - en: { - one: 'Data not deleted by {count} Service Node. Service Node ID: {service_node_id}.', - other: 'Data not deleted by {count} Service Nodes. Service Node IDs: {service_node_id}.', + en:{ + one: "Data not deleted by {count} Service Node. Service Node ID: {service_node_id}.", + other: "Data not deleted by {count} Service Nodes. Service Node IDs: {service_node_id}." }, - args: { count: 'number', service_node_id: 'string' }, + args: {count: "number", service_node_id: "string"} }, deleteMessage: { - en: { - one: 'Delete Message', - other: 'Delete Messages', + en:{ + one: "Delete Message", + other: "Delete Messages" }, - args: { count: 'number' }, + args: {count: "number"} }, deleteMessageConfirm: { - en: { - one: 'Are you sure you want to delete this message?', - other: 'Are you sure you want to delete these messages?', + en:{ + one: "Are you sure you want to delete this message?", + other: "Are you sure you want to delete these messages?" }, - args: { count: 'number' }, + args: {count: "number"} }, deleteMessageDeleted: { - en: { - one: 'Message deleted', - other: 'Messages deleted', + en:{ + one: "Message deleted", + other: "Messages deleted" }, - args: { count: 'number' }, + args: {count: "number"} }, deleteMessageDescriptionDevice: { - en: { - one: 'Are you sure you want to delete this message from this device only?', - other: 'Are you sure you want to delete these messages from this device only?', + en:{ + one: "Are you sure you want to delete this message from this device only?", + other: "Are you sure you want to delete these messages from this device only?" }, - args: { count: 'number' }, + args: {count: "number"} }, deleteMessageFailed: { - en: { - one: 'Failed to delete message', - other: 'Failed to delete messages', + en:{ + one: "Failed to delete message", + other: "Failed to delete messages" }, - args: { count: 'number' }, + args: {count: "number"} }, deleteMessageNoteToSelfWarning: { - en: { - one: 'This message cannot be deleted from all your devices', - other: 'Some of the messages you have selected cannot be deleted from all your devices', + en:{ + one: "This message cannot be deleted from all your devices", + other: "Some of the messages you have selected cannot be deleted from all your devices" }, - args: { count: 'number' }, + args: {count: "number"} }, deleteMessageWarning: { - en: { - one: 'This message cannot be deleted for everyone', - other: 'Some of the messages you have selected cannot be deleted for everyone', + en:{ + one: "This message cannot be deleted for everyone", + other: "Some of the messages you have selected cannot be deleted for everyone" }, - args: { count: 'number' }, + args: {count: "number"} }, emojiReactsCountOthers: { - en: { - one: 'And {count} other has reacted {emoji} to this message.', - other: 'And {count} others have reacted {emoji} to this message.', + en:{ + one: "And {count} other has reacted {emoji} to this message.", + other: "And {count} others have reacted {emoji} to this message." }, - args: { count: 'number', emoji: 'string' }, + args: {count: "number", emoji: "string"} }, groupInviteSending: { - en: { - one: 'Sending invite', - other: 'Sending invites', + en:{ + one: "Sending invite", + other: "Sending invites" }, - args: { count: 'number' }, + args: {count: "number"} }, groupRemoveMessages: { - en: { - one: 'Remove user and their messages', - other: 'Remove users and their messages', + en:{ + one: "Remove user and their messages", + other: "Remove users and their messages" }, - args: { count: 'number' }, + args: {count: "number"} }, groupRemoveUserOnly: { - en: { - one: 'Remove user', - other: 'Remove users', + en:{ + one: "Remove user", + other: "Remove users" }, - args: { count: 'number' }, + args: {count: "number"} }, inviteFailed: { - en: { - one: 'Invite Failed', - other: 'Invites Failed', + en:{ + one: "Invite Failed", + other: "Invites Failed" }, - args: { count: 'number' }, + args: {count: "number"} }, inviteFailedDescription: { - en: { - one: 'The invite could not be sent. Would you like to try again?', - other: 'The invites could not be sent. Would you like to try again?', + en:{ + one: "The invite could not be sent. Would you like to try again?", + other: "The invites could not be sent. Would you like to try again?" }, - args: { count: 'number' }, + args: {count: "number"} }, members: { - en: { - one: '{count} member', - other: '{count} members', + en:{ + one: "{count} member", + other: "{count} members" }, - args: { count: 'number' }, + args: {count: "number"} }, membersActive: { - en: { - one: '{count} active member', - other: '{count} active members', + en:{ + one: "{count} active member", + other: "{count} active members" }, - args: { count: 'number' }, + args: {count: "number"} }, membersInviteSend: { - en: { - one: 'Send Invite', - other: 'Send Invites', + en:{ + one: "Send Invite", + other: "Send Invites" }, - args: { count: 'number' }, + args: {count: "number"} }, messageNew: { - en: { - one: 'New Message', - other: 'New Messages', + en:{ + one: "New Message", + other: "New Messages" }, - args: { count: 'number' }, + args: {count: "number"} }, messageNewYouveGot: { - en: { + en:{ one: "You've got a new message.", - other: "You've got {count} new messages.", + other: "You've got {count} new messages." }, - args: { count: 'number' }, + args: {count: "number"} }, messageNewYouveGotGroup: { - en: { + en:{ one: "You've got a new message in {group_name}.", - other: "You've got {count} new messages in {group_name}.", + other: "You've got {count} new messages in {group_name}." }, - args: { group_name: 'string', count: 'number' }, + args: {group_name: "string", count: "number"} + }, + modalMessageCharacterDisplayDescription: { + en:{ + one: "Messages have a character limit of {limit} characters. You have {count} character remaining", + other: "Messages have a character limit of {limit} characters. You have {count} characters remaining" + }, + args: {limit: "string", count: "number"} }, promotionFailed: { - en: { - one: 'Promotion Failed', - other: 'Promotions Failed', + en:{ + one: "Promotion Failed", + other: "Promotions Failed" }, - args: { count: 'number' }, + args: {count: "number"} }, promotionFailedDescription: { - en: { - one: 'The promotion could not be applied. Would you like to try again?', - other: 'The promotions could not be applied. Would you like to try again?', + en:{ + one: "The promotion could not be applied. Would you like to try again?", + other: "The promotions could not be applied. Would you like to try again?" + }, + args: {count: "number"} + }, + remainingCharactersTooltip: { + en:{ + one: "{count} character remaining", + other: "{count} characters remaining" }, - args: { count: 'number' }, + args: {count: "number"} }, searchMatches: { - en: { - one: '{found_count} of {count} match', - other: '{found_count} of {count} matches', + en:{ + one: "{found_count} of {count} match", + other: "{found_count} of {count} matches" }, - args: { found_count: 'number', count: 'number' }, + args: {found_count: "number", count: "number"} }, } as const;